diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index c936660ae..a87e1280a 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/Engine/source/gui/core/guiCanvas.cpp @@ -231,6 +231,12 @@ bool GuiCanvas::onAdd() { // ensure that we have a cursor setCursor(dynamic_cast(Sim::findObject("DefaultCursor"))); + + SFXSystem::enumerateProviders(); + SFXProvider* p = SFXSystem::getBestProviderChoice(); + + if (p) + SFX->createDevice(p); // Enumerate things for GFX before we have an active device. GFXInit::enumerateAdapters(); diff --git a/Engine/source/sfx/dsound/dsFunctions.h b/Engine/source/sfx/dsound/dsFunctions.h deleted file mode 100644 index ad7a3e53b..000000000 --- a/Engine/source/sfx/dsound/dsFunctions.h +++ /dev/null @@ -1,27 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -// The various functions we need to grab from DSound.dll -DS_FUNCTION( DirectSoundEnumerateA, HRESULT, (LPDSENUMCALLBACKA pDSEnumCallback, LPVOID pContext) ) -DS_FUNCTION( DirectSoundEnumerateW, HRESULT, (LPDSENUMCALLBACKW pDSEnumCallback, LPVOID pContext) ) -DS_FUNCTION( DirectSoundCreate8, HRESULT, (LPCGUID pcGuidDevice, LPDIRECTSOUND8 *ppDS8, LPUNKNOWN pUnkOuter) ) - diff --git a/Engine/source/sfx/dsound/sfxDSBuffer.cpp b/Engine/source/sfx/dsound/sfxDSBuffer.cpp deleted file mode 100644 index d7d7bb9d9..000000000 --- a/Engine/source/sfx/dsound/sfxDSBuffer.cpp +++ /dev/null @@ -1,277 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "sfx/dsound/sfxDSBuffer.h" -#include "sfx/sfxStream.h" -#include "sfx/sfxDescription.h" -#include "sfx/sfxInternal.h" -#include "platform/async/asyncUpdate.h" -#include "core/util/safeRelease.h" -#include "core/util/safeCast.h" - - -SFXDSBuffer* SFXDSBuffer::create( IDirectSound8 *dsound, - const ThreadSafeRef< SFXStream >& stream, - SFXDescription* description, - bool useHardware ) -{ - AssertFatal( dsound, "SFXDSBuffer::create() - Got null dsound!" ); - AssertFatal( stream, "SFXDSBuffer::create() - Got a null stream!" ); - AssertFatal( description, "SFXDSBuffer::create() - Got a null description" ); - - SFXDSBuffer* buffer = new SFXDSBuffer( dsound, - stream, - description, - useHardware ); - - - if( !buffer->_createBuffer( &buffer->mBuffer ) ) - SAFE_DELETE( buffer ); - - return buffer; -} - -SFXDSBuffer::SFXDSBuffer( IDirectSound8* dsound, - const ThreadSafeRef< SFXStream >& stream, - SFXDescription* description, - bool useHardware ) - : Parent( stream, description ), - mDSound( dsound ), - mIs3d( description->mIs3D ), - mUseHardware( useHardware ), - mBuffer( NULL ), - mDuplicate( false ) -{ - AssertFatal( mDSound, "SFXDSBuffer::SFXDSBuffer() - Got null dsound!" ); - - mDSound->AddRef(); -} - -SFXDSBuffer::~SFXDSBuffer() -{ - SAFE_RELEASE( mBuffer ); - SAFE_RELEASE( mDSound ); -} - -bool SFXDSBuffer::_createBuffer( IDirectSoundBuffer8 **buffer8 ) -{ - AssertFatal( mAsyncState != NULL, - "SFXDSBuffer::_createBuffer() - Can't create buffer when not connected to stream!" ); - - const SFXFormat& format = getFormat(); - - // Set up WAV format structure. - WAVEFORMATEX wfx; - dMemset( &wfx, 0, sizeof( WAVEFORMATEX ) ); - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nChannels = format.getChannels(); - wfx.nSamplesPerSec = format.getSamplesPerSecond(); - wfx.wBitsPerSample = format.getBitsPerChannel(); - wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; - wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - - // Set up DSBUFFERDESC structure. - DSBUFFERDESC dsbdesc; - dMemset( &dsbdesc, 0, sizeof( DSBUFFERDESC ) ); - dsbdesc.dwSize = sizeof( DSBUFFERDESC ); - dsbdesc.dwFlags = - ( mIs3d ? DSBCAPS_CTRL3D | DSBCAPS_MUTE3DATMAXDISTANCE : DSBCAPS_CTRLPAN ) | - ( isStreaming() ? DSBCAPS_CTRLPOSITIONNOTIFY : 0 ) | - DSBCAPS_CTRLFREQUENCY | - DSBCAPS_CTRLVOLUME | - DSBCAPS_GETCURRENTPOSITION2 | - DSBCAPS_GLOBALFOCUS | - DSBCAPS_STATIC | - ( mUseHardware ? DSBCAPS_LOCHARDWARE : DSBCAPS_LOCSOFTWARE ); - dsbdesc.dwBufferBytes = mBufferSize; - if ( mIs3d ) - dsbdesc.guid3DAlgorithm = DS3DALG_HRTF_FULL; - dsbdesc.lpwfxFormat = &wfx; - - // Create the buffer. - IDirectSoundBuffer *buffer = NULL; - HRESULT hr = mDSound->CreateSoundBuffer( &dsbdesc, &buffer, NULL ); - if ( FAILED( hr ) || !buffer ) - return false; - - // Grab the version 8 interface. - IDirectSoundBuffer8* buffer8Ptr; - hr = buffer->QueryInterface( IID_IDirectSoundBuffer8, ( LPVOID* ) &buffer8Ptr ); - - // Release the original interface. - buffer->Release(); - - // If we failed to get the 8 interface... exit. - if ( FAILED( hr ) || !buffer8Ptr ) - return false; - - // Set up notification positions, if this is a streaming buffer. - - if( isStreaming() ) - { - using namespace SFXInternal; - - const U32 maxQueuedPackets = SFXAsyncQueue::DEFAULT_STREAM_QUEUE_LENGTH; - const U32 packetSize = mAsyncState->mStream->getPacketSize(); - - LPDIRECTSOUNDNOTIFY8 lpDsNotify; - if( FAILED( hr = buffer8Ptr->QueryInterface( IID_IDirectSoundNotify8, ( LPVOID* ) &lpDsNotify ) ) ) - { - SAFE_RELEASE( buffer8Ptr ); - return false; - } - - const U32 numNotifies = maxQueuedPackets + 1; // Add one for end-of-stream notification pos. - DSBPOSITIONNOTIFY* dsbNotifyPos = - ( DSBPOSITIONNOTIFY* ) _alloca( numNotifies * sizeof( DSBPOSITIONNOTIFY ) ); - - // Events seem to be triggered way too early by DS causing the playback queues to - // reject updates, so we nudge the update markers "somewhat" to the right here. - // This value here is based on experimentation. No harm should result if we don't - // hit it other than updates happening in sub-optimal timing. - enum { OFFSET_DELTA = 5000 }; - - U32 offset = ( packetSize + OFFSET_DELTA ) % mBufferSize; - HANDLE updateEvent = ( HANDLE ) UPDATE_THREAD()->getUpdateEvent(); - for( U32 i = 0; i < maxQueuedPackets; ++ i, offset = ( offset + packetSize ) % mBufferSize ) - { - dsbNotifyPos[ i ].dwOffset = offset; - dsbNotifyPos[ i ].hEventNotify = updateEvent; - } - - // A end-of-stream notification position. - - //FIXME: this position will start to be wrong when doing stream seeks - - dsbNotifyPos[ numNotifies - 1 ].dwOffset = ( format.getDataLength( getDuration() ) + OFFSET_DELTA ) % mBufferSize; - dsbNotifyPos[ numNotifies - 1 ].hEventNotify = updateEvent; - - // Install the notifications. - - lpDsNotify->SetNotificationPositions( numNotifies, dsbNotifyPos ); - SAFE_RELEASE( lpDsNotify ); - - // Don't need to notify on stop as when playback is stopped, - // the packet buffers will just fill up and stop updating - // when saturated. - } - - *buffer8 = buffer8Ptr; - return true; -} - -bool SFXDSBuffer::_copyData( U32 offset, - const U8 *data, - U32 length ) -{ - AssertFatal( mBuffer, "SFXDSBuffer::_copyData() - no buffer" ); - - // Fill the buffer with the resource data. - VOID* lpvWrite; - DWORD dwLength; - VOID* lpvWrite2; - DWORD dwLength2; - HRESULT hr = mBuffer->Lock( - offset, // Offset at which to start lock. - length, // Size of lock. - &lpvWrite, // Gets address of first part of lock. - &dwLength, // Gets size of first part of lock. - &lpvWrite2, // Address of wraparound not needed. - &dwLength2, // Size of wraparound not needed. - 0 ); - if ( FAILED( hr ) ) - return false; - - // Copy the first part. - dMemcpy( lpvWrite, data, dwLength ); - - // Do we have a wrap? - if ( lpvWrite2 ) - dMemcpy( lpvWrite2, data + dwLength, dwLength2 ); - - // And finally, unlock. - hr = mBuffer->Unlock( - lpvWrite, // Address of lock start. - dwLength, // Size of lock. - lpvWrite2, // No wraparound portion. - dwLength2 ); // No wraparound size. - - // Return success code. - return SUCCEEDED(hr); -} - -void SFXDSBuffer::_flush() -{ - AssertFatal( isStreaming(), "SFXDSBuffer::_flush() - not a streaming buffer" ); - AssertFatal( SFXInternal::isSFXThread(), "SFXDSBuffer::_flush() - not on SFX thread" ); - - Parent::_flush(); - mBuffer->SetCurrentPosition( 0 ); -} - -bool SFXDSBuffer::_duplicateBuffer( IDirectSoundBuffer8 **buffer8 ) -{ - AssertFatal( mBuffer, "SFXDSBuffer::_duplicateBuffer() - Duplicate buffer is null!" ); - - // If this is the first duplicate then - // give the caller our original buffer. - if ( !mDuplicate ) - { - mDuplicate = true; - - *buffer8 = mBuffer; - (*buffer8)->AddRef(); - - return true; - } - - IDirectSoundBuffer *buffer1 = NULL; - HRESULT hr = mDSound->DuplicateSoundBuffer( mBuffer, &buffer1 ); - if ( FAILED( hr ) || !buffer1 ) - return false; - - // Grab the version 8 interface. - hr = buffer1->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*)buffer8 ); - - // Release the original interface. - buffer1->Release(); - - return SUCCEEDED( hr ) && (*buffer8); -} - -bool SFXDSBuffer::createVoice( IDirectSoundBuffer8 **buffer8 ) -{ - return ( mBuffer && _duplicateBuffer( buffer8 ) && *buffer8 ); -} - -void SFXDSBuffer::releaseVoice( IDirectSoundBuffer8 **buffer ) -{ - AssertFatal( *buffer, "SFXDSBuffer::releaseVoice() - Got null buffer!" ); - - if ( *buffer == mBuffer ) - { - mDuplicate = false; - (*buffer)->Stop(); - } - - SAFE_RELEASE( (*buffer) ); -} diff --git a/Engine/source/sfx/dsound/sfxDSBuffer.h b/Engine/source/sfx/dsound/sfxDSBuffer.h deleted file mode 100644 index 94549df86..000000000 --- a/Engine/source/sfx/dsound/sfxDSBuffer.h +++ /dev/null @@ -1,101 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _SFXDSBUFFER_H_ -#define _SFXDSBUFFER_H_ - -#include - -#ifndef _SFXINTERNAL_H_ -# include "sfx/sfxInternal.h" -#endif - - -/// DirectSound SFXBuffer implementation. -/// -/// Note that the actual sound buffer held by the buffer may -/// get duplicated around for individual voices. This is kind -/// of ugly as the resulting buffers aren't tied to a SFXDSBuffer -/// anymore. -class SFXDSBuffer : public SFXInternal::SFXWrapAroundBuffer -{ - typedef SFXInternal::SFXWrapAroundBuffer Parent; - - friend class SFXDSDevice; - friend class SFXDSVoice; - - protected: - - /// - bool mIs3d; - - /// - bool mUseHardware; - - IDirectSound8 *mDSound; - - /// The buffer used when duplication is allowed. - IDirectSoundBuffer8 *mBuffer; - - /// We set this to true when the original buffer has - /// been handed out and duplicates need to be made. - bool mDuplicate; - - /// - SFXDSBuffer( IDirectSound8 *dsound, - const ThreadSafeRef< SFXStream >& stream, - SFXDescription* description, - bool useHardware ); - - virtual ~SFXDSBuffer(); - - /// Set up a DirectSound buffer. - /// @note This method will not fill the buffer with data. - /// @note If this is a streaming buffer, the resulting buffer - /// will have its notification positions set up and already - /// be registered with SFXDSStreamThread. - bool _createBuffer( IDirectSoundBuffer8 **buffer8 ); - - /// - bool _duplicateBuffer( IDirectSoundBuffer8 **buffer8 ); - - // SFXWrapAroundBuffer. - virtual bool _copyData( U32 offset, const U8* data, U32 length ); - virtual void _flush(); - -public: - - /// - static SFXDSBuffer* create( IDirectSound8* dsound, - const ThreadSafeRef< SFXStream >& stream, - SFXDescription* description, - bool useHardware ); - - // - bool createVoice( IDirectSoundBuffer8 **buffer ); - - // - void releaseVoice( IDirectSoundBuffer8 **buffer ); - -}; - -#endif // _SFXDSBUFFER_H_ \ No newline at end of file diff --git a/Engine/source/sfx/dsound/sfxDSDevice.cpp b/Engine/source/sfx/dsound/sfxDSDevice.cpp deleted file mode 100644 index b83ed120c..000000000 --- a/Engine/source/sfx/dsound/sfxDSDevice.cpp +++ /dev/null @@ -1,229 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "sfx/dsound/sfxDSDevice.h" -#include "sfx/dsound/sfxDSBuffer.h" -#include "sfx/dsound/sfxDSVoice.h" -#include "platformWin32/platformWin32.h" -#include "core/util/safeRelease.h" -#include "platform/async/asyncUpdate.h" -#include "console/console.h" - - -SFXDSDevice::SFXDSDevice( SFXProvider* provider, - DSoundFNTable *dsFnTbl, - GUID* guid, - String name, - bool useHardware, - S32 maxBuffers ) - : SFXDevice( name, provider, useHardware, maxBuffers ), - mDSound( NULL ), - mPrimaryBuffer( NULL ), - mListener( NULL ), - mDSoundTbl( dsFnTbl ), - mGUID( guid ) -{ -} - -bool SFXDSDevice::_init() -{ - HRESULT hr = mDSoundTbl->DirectSoundCreate8( mGUID, &mDSound, NULL ); - if ( FAILED( hr ) || !mDSound ) - { - Con::errorf( "SFXDSDevice::SFXDSDevice() - DirectSoundCreate8 failed" ); - return false; - } - - hr = mDSound->SetCooperativeLevel( getWin32WindowHandle(), DSSCL_PRIORITY ); - if ( FAILED( hr ) ) - { - Con::errorf( "SFXDSDevice::SFXDSDevice() - SetCooperativeLevel failed" ); - return false; - } - - // Get the primary buffer. - DSBUFFERDESC dsbd; - dMemset( &dsbd, 0, sizeof( DSBUFFERDESC ) ); - dsbd.dwSize = sizeof( DSBUFFERDESC ); - dsbd.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER; - hr = mDSound->CreateSoundBuffer( &dsbd, &mPrimaryBuffer, NULL ); - if ( FAILED( hr ) ) - { - Con::errorf( "SFXDSDevice::SFXDSDevice - Creating primary sound buffer failed" ); - return false; - } - - // Set the format and bitrate on the primary buffer. - S32 frequency = Con::getIntVariable( "$pref::SFX::frequency", 44100 ); - S32 bitrate = Con::getIntVariable( "$pref::SFX::bitrate", 32 ); - - WAVEFORMATEX wfx; - dMemset( &wfx, 0, sizeof( WAVEFORMATEX ) ); - wfx.wFormatTag = WAVE_FORMAT_PCM; - wfx.nChannels = 2; - wfx.nSamplesPerSec = frequency; - wfx.wBitsPerSample = bitrate; - wfx.nBlockAlign = ( wfx.nChannels * wfx.wBitsPerSample ) / 8; - wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; - hr = mPrimaryBuffer->SetFormat( &wfx ); - if( FAILED( hr ) ) - { - Con::errorf( "SFXDSDevice::SFXDSDevice() - Setting format of primary buffer failed" ); - return false; - } - - // Grab the 3d listener. - hr = mPrimaryBuffer->QueryInterface( IID_IDirectSound3DListener8, (LPVOID*)&mListener ); - if ( FAILED( hr ) ) - { - Con::errorf( "SFXDSDevice::SFXDevice() - Querying the listener interface failed!" ); - mListener = NULL; - } - - mCaps.dwSize = sizeof( DSCAPS ); - mDSound->GetCaps( &mCaps ); - - // If the device reports no hardware buffers then - // we have no choice but to disable hardware. - if ( mCaps.dwMaxHw3DAllBuffers == 0 ) - mUseHardware = false; - - // If mMaxBuffers is negative then use the caps - // to decide on a good maximum value... or set 8. - if ( mMaxBuffers < 0 ) - mMaxBuffers = getMax( mCaps.dwMaxHw3DAllBuffers, 8 ); - - // Start the stream thread. - - if( !Con::getBoolVariable( "$_forceAllMainThread" ) ) - { - SFXInternal::gUpdateThread = - new AsyncUpdateThread( "DirectSound Update Thread", SFXInternal::gBufferUpdateList ); - SFXInternal::gUpdateThread->start(); - } - - return true; -} - -SFXDSDevice::~SFXDSDevice() -{ - // And release our resources. - SAFE_RELEASE( mListener ); - SAFE_RELEASE( mPrimaryBuffer ); - SAFE_RELEASE( mDSound ); -} - -SFXBuffer* SFXDSDevice::createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ) -{ - AssertFatal( stream, "SFXDSDevice::createBuffer() - Got null stream!" ); - AssertFatal( description, "SFXDSDevice::createBuffer() - Got null description!" ); - - SFXDSBuffer* buffer = SFXDSBuffer::create( mDSound, - stream, - description, - mUseHardware ); - - if( buffer ) - _addBuffer( buffer ); - - return buffer; -} - -SFXVoice* SFXDSDevice::createVoice( bool is3D, SFXBuffer *buffer ) -{ - // Don't bother going any further if we've - // exceeded the maximum voices. - if ( mVoices.size() >= mMaxBuffers ) - return NULL; - - AssertFatal( buffer, "SFXDSDevice::createVoice() - Got null buffer!" ); - - SFXDSBuffer* dsBuffer = dynamic_cast( buffer ); - AssertFatal( dsBuffer, "SFXDSDevice::createVoice() - Got bad buffer!" ); - - SFXDSVoice* voice = SFXDSVoice::create( this, dsBuffer ); - if ( !voice ) - return NULL; - - _addVoice( voice ); - return voice; -} - -void SFXDSDevice::_commitDeferred() -{ - if( mListener ) - mListener->CommitDeferredSettings(); -} - -void SFXDSDevice::update() -{ - Parent::update(); - - // Apply the deferred settings that changed between updates. - mListener->CommitDeferredSettings(); -} - -void SFXDSDevice::setListener( U32 index, const SFXListenerProperties& listener ) -{ - // Get the transform from the listener. - const MatrixF& transform = listener.getTransform(); - Point3F pos, dir, up; - transform.getColumn( 3, &pos ); - transform.getColumn( 1, &dir ); - transform.getColumn( 2, &up ); - - // And the velocity... - const VectorF& velocity = listener.getVelocity(); - - // Finally, set it all to DSound! - mListener->SetPosition( pos.x, pos.z, pos.y, DS3D_DEFERRED ); - mListener->SetOrientation( dir.x, dir.z, dir.y, up.x, up.z, up.y, DS3D_DEFERRED ); - mListener->SetVelocity( velocity.x, velocity.z, velocity.y, DS3D_DEFERRED ); -} - -void SFXDSDevice::setDistanceModel( SFXDistanceModel model ) -{ - switch( model ) - { - case SFXDistanceModelLinear: - Con::errorf( "SFXDSDevice::setDistanceModel - 'linear' distance attenuation not supported by DirectSound" ); - break; - - case SFXDistanceModelLogarithmic: - break; // Nothing to do. - - default: - AssertWarn( false, "SFXDSDevice::setDistanceModel() - model not implemented" ); - } -} - -void SFXDSDevice::setDopplerFactor( F32 factor ) -{ - if( mListener ) - mListener->SetDopplerFactor( factor, DS3D_DEFERRED ); // Committed in update. -} - -void SFXDSDevice::setRolloffFactor( F32 factor ) -{ - if( mListener ) - mListener->SetRolloffFactor( factor, DS3D_DEFERRED ); // Committed in update. -} diff --git a/Engine/source/sfx/dsound/sfxDSDevice.h b/Engine/source/sfx/dsound/sfxDSDevice.h deleted file mode 100644 index 540294c85..000000000 --- a/Engine/source/sfx/dsound/sfxDSDevice.h +++ /dev/null @@ -1,142 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _SFXDSDEVICE_H_ -#define _SFXDSDEVICE_H_ - -#ifndef _STRINGFUNCTIONS_H_ -# include "core/strings/stringFunctions.h" -#endif -#ifndef _SFXDEVICE_H_ - #include "sfx/sfxDevice.h" -#endif -#ifndef _SFXDSVOICE_H_ - #include "sfx/dsound/sfxDSVoice.h" -#endif -#ifndef OS_DLIBRARY_H - #include "platform/platformDlibrary.h" -#endif - -#include - -// Typedefs -#define DS_FUNCTION(fn_name, fn_return, fn_args) \ - typedef fn_return (WINAPI *DSFNPTR##fn_name##)##fn_args##; -#include "sfx/dsound/dsFunctions.h" -#undef DS_FUNCTION - -// Function table -struct DSoundFNTable -{ - DSoundFNTable() : isLoaded( false ) {}; - bool isLoaded; - DLibraryRef dllRef; - -#define DS_FUNCTION(fn_name, fn_return, fn_args) \ - DSFNPTR##fn_name fn_name; -#include "sfx/dsound/dsFunctions.h" -#undef DS_FUNCTION -}; - - -/// Helper for asserting on dsound HRESULTS. -inline void DSAssert( HRESULT hr, const char *info ) -{ - #ifdef TORQUE_DEBUG - - if( FAILED( hr ) ) - { - char buf[256]; - dSprintf( buf, 256, "Error code: %x\n%s", hr, info ); - AssertFatal( false, buf ); - } - - #endif -} - - -/// The DirectSound device implementation exposes a couple -/// of settings to script that you should be aware of: -/// -/// $DirectSound::dopplerFactor - This controls the scale of -/// the doppler effect. Valid factors are 0.0 to 10.0 and it -/// defaults to 0.75. -/// -/// $DirectSound::distanceFactor - This sets the unit conversion -/// for -/// -/// $DirectSound::rolloffFactor - ; -/// -/// -class SFXDSDevice : public SFXDevice -{ - typedef SFXDevice Parent; - - friend class SFXDSVoice; - friend class SFXDSProvider; // _init - - public: - - //explicit SFXDSDevice(); - - SFXDSDevice( SFXProvider* provider, - DSoundFNTable *dsFnTbl, - GUID* guid, - String name, - bool useHardware, - S32 maxBuffers ); - - virtual ~SFXDSDevice(); - - protected: - - IDirectSound8 *mDSound; - - IDirectSound3DListener8 *mListener; - - IDirectSoundBuffer *mPrimaryBuffer; - - DSoundFNTable *mDSoundTbl; - - DSCAPS mCaps; - - GUID* mGUID; - - bool _init(); - - /// Called from SFXDSVoice to commit any deferred - /// settings before playback begins. - void _commitDeferred(); - - public: - - // SFXDevice - virtual SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ); - virtual SFXVoice* createVoice( bool is3D, SFXBuffer *buffer ); - virtual void update(); - virtual void setListener( U32 index, const SFXListenerProperties& listener ); - virtual void setDistanceModel( SFXDistanceModel mode ); - virtual void setDopplerFactor( F32 factor ); - virtual void setRolloffFactor( F32 factor ); -}; - -#endif // _SFXDSDEVICE_H_ diff --git a/Engine/source/sfx/dsound/sfxDSProvider.cpp b/Engine/source/sfx/dsound/sfxDSProvider.cpp deleted file mode 100644 index a18101484..000000000 --- a/Engine/source/sfx/dsound/sfxDSProvider.cpp +++ /dev/null @@ -1,198 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "sfx/sfxProvider.h" -#include "sfx/dsound/sfxDSDevice.h" -#include "core/util/safeRelease.h" -#include "console/console.h" -#include "core/strings/unicode.h" -#include "core/util/safeDelete.h" -#include "core/module.h" - - -class SFXDSProvider : public SFXProvider -{ -public: - - SFXDSProvider() - : SFXProvider( "DirectSound" ) {} - virtual ~SFXDSProvider(); - - void init(); - -protected: - DSoundFNTable mDSound; - - struct DSDeviceInfo : SFXDeviceInfo - { - GUID* guid; - DSCAPS caps; - }; - - static BOOL CALLBACK dsEnumProc( - LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ); - - void addDeviceDesc( GUID* guid, const String& name, const String& desc ); - -public: - - SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ); - -}; - -MODULE_BEGIN( DirectSound ) - - MODULE_INIT_BEFORE( SFX ) - MODULE_SHUTDOWN_AFTER( SFX ) - - SFXDSProvider* mProvider; - - MODULE_INIT - { - mProvider = new SFXDSProvider; - } - - MODULE_SHUTDOWN - { - delete mProvider; - } - -MODULE_END; - -//------------------------------------------------------------------------------ -// Helper - -bool dsBindFunction( DLibrary *dll, void *&fnAddress, const char *name ) -{ - fnAddress = dll->bind( name ); - - if (!fnAddress) - Con::warnf( "DSound Loader: DLL bind failed for %s", name ); - - return fnAddress != 0; -} - -//------------------------------------------------------------------------------ - -SFXDSProvider::~SFXDSProvider() -{ -} - -void SFXDSProvider::init() -{ - // Grab the functions we'll want from the dsound DLL. - mDSound.dllRef = OsLoadLibrary( "dsound.dll" ); - mDSound.isLoaded = true; -#define DS_FUNCTION(fn_name, fn_return, fn_args) \ - mDSound.isLoaded &= dsBindFunction(mDSound.dllRef, *(void**)&mDSound.fn_name, #fn_name); -#include "sfx/dsound/dsFunctions.h" -#undef DS_FUNCTION - - AssertISV( mDSound.isLoaded, "DirectSound failed to load." ); - - // All we need to do to init is enumerate the - // devices... if this fails then don't register - // the provider as it's broken in some way. - if ( FAILED( mDSound.DirectSoundEnumerate( dsEnumProc, (VOID*)this ) ) ) - { - Con::errorf( "SFXDSProvider - Device enumeration failed!" ); - return; - } - - // Did we get any devices? - if ( mDeviceInfo.empty() ) - { - Con::errorf( "SFXDSProvider - No valid devices found!" ); - return; - } - - // Wow, we made it - register the provider. - regProvider( this ); -} - - -BOOL CALLBACK SFXDSProvider::dsEnumProc( - LPGUID lpGUID, - LPCTSTR lpszDesc, - LPCTSTR lpszDrvName, - LPVOID lpContext ) -{ - SFXDSProvider* provider = (SFXDSProvider*)lpContext; - provider->addDeviceDesc( lpGUID, lpszDrvName, lpszDesc ); - return TRUE; -} - -void SFXDSProvider::addDeviceDesc( GUID* guid, const String& name, const String& desc ) -{ - // Create a dummy device to get the caps. - IDirectSound8* dsound; - HRESULT hr = mDSound.DirectSoundCreate8( guid, &dsound, NULL ); - if ( FAILED( hr ) || !dsound ) - return; - - // Init the caps structure and have the device fill it out. - DSCAPS caps; - dMemset( &caps, 0, sizeof( caps ) ); - caps.dwSize = sizeof( caps ); - hr = dsound->GetCaps( &caps ); - - // Clean up and handle errors. - SAFE_RELEASE( dsound ); - - if ( FAILED( hr ) ) - return; - - // Now, record the desc info into our own internal list. - DSDeviceInfo* info = new DSDeviceInfo; - info->name = desc; - info->driver = name; - info->hasHardware = caps.dwMaxHw3DAllBuffers > 0; - info->maxBuffers = caps.dwMaxHw3DAllBuffers; - info->guid = guid; - info->caps = caps; - - mDeviceInfo.push_back( info ); -} - -SFXDevice* SFXDSProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ) -{ - DSDeviceInfo* info = dynamic_cast< DSDeviceInfo* > - ( _findDeviceInfo( deviceName ) ); - - if( !info ) - return NULL; - - SFXDSDevice* device = new SFXDSDevice( this, - &mDSound, - info->guid, - info->name, - useHardware, - maxBuffers ); - - if( !device->_init() ) - SAFE_DELETE( device ); - - return device; -} diff --git a/Engine/source/sfx/dsound/sfxDSVoice.cpp b/Engine/source/sfx/dsound/sfxDSVoice.cpp deleted file mode 100644 index ffabec043..000000000 --- a/Engine/source/sfx/dsound/sfxDSVoice.cpp +++ /dev/null @@ -1,229 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "sfx/dsound/sfxDSVoice.h" -#include "sfx/dsound/sfxDSDevice.h" -#include "core/util/safeRelease.h" - - -SFXDSVoice* SFXDSVoice::create( SFXDSDevice *device, SFXDSBuffer *buffer ) -{ - AssertFatal( buffer, "SFXDSVoice::create() - Got null buffer!" ); - - IDirectSoundBuffer8 *dsBuffer8 = NULL; - if ( !buffer->createVoice( &dsBuffer8 ) || !dsBuffer8 ) - return NULL; - - // Now try to grab a 3D interface... if we don't - // get one its probably because its not a 3d sound. - IDirectSound3DBuffer8* dsBuffer3d8 = NULL; - dsBuffer8->QueryInterface( IID_IDirectSound3DBuffer8, (LPVOID*)&dsBuffer3d8 ); - - // Create the voice and return! - SFXDSVoice* voice = new SFXDSVoice( device, - buffer, - dsBuffer8, - dsBuffer3d8 ); - - // Now set the voice to a default state. - // The buffer from which we have duplicated may have been assigned different - // properties and we don't want to inherit these. - - voice->setVolume( 1.0 ); - voice->setPitch( 1.0 ); - - return voice; -} - -SFXDSVoice::SFXDSVoice( SFXDSDevice *device, - SFXDSBuffer *buffer, - IDirectSoundBuffer8 *dsBuffer, - IDirectSound3DBuffer8 *dsBuffer3d ) - : Parent( buffer ), - mDevice( device ), - mDSBuffer( dsBuffer ), - mDSBuffer3D( dsBuffer3d ), - mIsLooping( false ) -{ - AssertFatal( mDevice, "SFXDSVoice::SFXDSVoice() - SFXDSDevice is null!" ); - AssertFatal( mBuffer, "SFXDSVoice::SFXDSVoice() - SFXDSBuffer is null!" ); - AssertFatal( mDSBuffer, "SFXDSVoice::SFXDSVoice() - Dsound buffer is null!" ); -} - -SFXDSVoice::~SFXDSVoice() -{ - SAFE_RELEASE( mDSBuffer3D ); - - SFXDSBuffer* dsBuffer = _getBuffer(); - if( dsBuffer ) - dsBuffer->releaseVoice( &mDSBuffer ); - - mBuffer = NULL; -} - -SFXStatus SFXDSVoice::_status() const -{ - DWORD status = 0; - mDSBuffer->GetStatus( &status ); - - if ( status & DSBSTATUS_PLAYING ) - return SFXStatusPlaying; - else - return SFXStatusStopped; -} - -void SFXDSVoice::_play() -{ - DSAssert( mDSBuffer->Play( 0, 0, mIsLooping ? DSBPLAY_LOOPING : 0 ), - "SFXDSVoice::_play() - Playback failed!" ); -} - -void SFXDSVoice::_stop() -{ - DSAssert( mDSBuffer->Stop(), "SFXDSVoice::pause - stop failed!" ); - mDSBuffer->SetCurrentPosition( 0 ); -} - -void SFXDSVoice::_pause() -{ - DSAssert( mDSBuffer->Stop(), "SFXDSVoice::pause - stop failed!" ); -} - -void SFXDSVoice::_seek( U32 sample ) -{ - U32 pos = mBuffer->getFormat().getBytesPerSample() * sample; - mDSBuffer->SetCurrentPosition( pos ); -} - -U32 SFXDSVoice::_tell() const -{ - DWORD position = 0; - mDSBuffer->GetCurrentPosition( &position, NULL ); - U32 samplePos = _getBuffer()->getSamplePos( position ); - return samplePos; -} - -void SFXDSVoice::setMinMaxDistance( F32 min, F32 max ) -{ - if ( !mDSBuffer3D ) - return; - - mDSBuffer3D->SetMinDistance( min, DS3D_DEFERRED ); - mDSBuffer3D->SetMaxDistance( max, DS3D_DEFERRED ); -} - -void SFXDSVoice::play( bool looping ) -{ - // If this is a 3d sound then we need - // to commit any deferred settings before - // we start playback else we can get some - // glitches. - - if ( mDSBuffer3D ) - mDevice->_commitDeferred(); - - // If this is a streaming buffer, - // force looping. - - const bool isStreaming = mBuffer->isStreaming(); - if( isStreaming ) - looping = true; - mIsLooping = looping; - - Parent::play( looping ); -} - -void SFXDSVoice::setVelocity( const VectorF& velocity ) -{ - if ( !mDSBuffer3D ) - return; - - DSAssert( mDSBuffer3D->SetVelocity( velocity.x, velocity.z, velocity.y, DS3D_DEFERRED ), - "SFXDSVoice::setVelocity - couldn't update buffer!" ); -} - -void SFXDSVoice::setTransform( const MatrixF& transform ) -{ - if ( !mDSBuffer3D ) - return; - - Point3F pos, dir; - transform.getColumn( 3, &pos ); - transform.getColumn( 1, &dir ); - DSAssert( mDSBuffer3D->SetPosition( pos.x, pos.z, pos.y, DS3D_DEFERRED ), - "SFXDSVoice::setTransform - couldn't set position of the buffer." ); - - DSAssert( mDSBuffer3D->SetConeOrientation( dir.x, dir.z, dir.y, DS3D_DEFERRED ), - "SFXDSVoice::setTransform - couldn't set cone orientation of the buffer." ); -} - -/// Helper for converting floating point linear volume -/// to a logrithmic integer volume for dsound. -LONG SFXDSVoice::_linearToLogVolume( F32 linVolume ) -{ - LONG logVolume; - - if ( linVolume <= 0.0f ) - logVolume = DSBVOLUME_MIN; - else - { - logVolume = -2000.0 * mLog( 1.0f / linVolume ); - logVolume = mClamp( logVolume, DSBVOLUME_MIN, DSBVOLUME_MAX ); - } - - return logVolume; -} - -void SFXDSVoice::setVolume( F32 volume ) -{ - LONG logVolume = _linearToLogVolume( volume ); - - HRESULT hr = mDSBuffer->SetVolume( logVolume ); - DSAssert( hr, "SFXDSVoice::setVolume - couldn't set volume!" ); -} - -void SFXDSVoice::setPitch( F32 pitch ) -{ - F32 sampleRate = _getBuffer()->getFormat().getSamplesPerSecond(); - F32 frequency = mFloor( mClampF( sampleRate * pitch, DSBFREQUENCY_MIN, DSBFREQUENCY_MAX ) ); - - DSAssert( mDSBuffer->SetFrequency( ( U32 )frequency ), - "SFXDSVoice::setPitch - couldn't set playback frequency."); -} - -void SFXDSVoice::setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume ) -{ - if ( !mDSBuffer3D ) - return; - - DSAssert( mDSBuffer3D->SetConeAngles( innerAngle, - outerAngle, - DS3D_DEFERRED ), - "SFXDSVoice::setCone - couldn't set cone angles!" ); - - - LONG logVolume = _linearToLogVolume( outerVolume ); - - DSAssert( mDSBuffer3D->SetConeOutsideVolume( logVolume, - DS3D_DEFERRED ), - "SFXDSVoice::setCone - couldn't set cone outside volume!" ); -} diff --git a/Engine/source/sfx/dsound/sfxDSVoice.h b/Engine/source/sfx/dsound/sfxDSVoice.h deleted file mode 100644 index e428832c1..000000000 --- a/Engine/source/sfx/dsound/sfxDSVoice.h +++ /dev/null @@ -1,92 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _SFXDSVOICE_H_ -#define _SFXDSVOICE_H_ - -#ifndef _SFXVOICE_H_ - #include "sfx/sfxVoice.h" -#endif -#ifndef _SFXDSBUFFER_H_ - #include "sfx/dsound/sfxDSBuffer.h" -#endif - -#include - -class SFXDSDevice; - - -class SFXDSVoice : public SFXVoice -{ - typedef SFXVoice Parent; - - protected: - - SFXDSVoice( SFXDSDevice *device, - SFXDSBuffer *buffer, - IDirectSoundBuffer8 *dsBuffer, - IDirectSound3DBuffer8 *dsBuffer3d ); - - /// The device used to commit deferred settings. - SFXDSDevice *mDevice; - - IDirectSoundBuffer8 *mDSBuffer; - - IDirectSound3DBuffer8 *mDSBuffer3D; - - bool mIsLooping; - - SFXDSBuffer* _getBuffer() const { return ( SFXDSBuffer* ) mBuffer.getPointer(); } - - /// Helper for converting floating point linear volume - /// to a logrithmic integer volume for dsound. - static LONG _linearToLogVolume( F32 linVolume ); - - // SFXVoice - virtual SFXStatus _status() const; - virtual void _play(); - virtual void _pause(); - virtual void _stop(); - virtual void _seek( U32 sample ); - virtual U32 _tell() const; - - public: - - /// - static SFXDSVoice* create( SFXDSDevice *device, - SFXDSBuffer *buffer ); - - /// - virtual ~SFXDSVoice(); - - // SFXVoice - void setMinMaxDistance( F32 min, F32 max ); - void play( bool looping ); - void setVelocity( const VectorF& velocity ); - void setTransform( const MatrixF& transform ); - void setVolume( F32 volume ); - void setPitch( F32 pitch ); - void setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume ); - -}; - -#endif // _SFXDSBUFFER_H_ \ No newline at end of file diff --git a/Engine/source/sfx/media/sfxSndStream.cpp b/Engine/source/sfx/media/sfxSndStream.cpp index eee6d5d69..d3652ae01 100644 --- a/Engine/source/sfx/media/sfxSndStream.cpp +++ b/Engine/source/sfx/media/sfxSndStream.cpp @@ -33,46 +33,127 @@ bool SFXSndStream::_readHeader() dMemset(&sfinfo, 0, sizeof(SF_INFO)); - vio.get_filelen = sndFileLen; - vio.seek = sndSeek; - vio.read = sndRead; - vio.write = sndWrite; - vio.tell = sndTell; + vio.get_filelen = sndFileLen; + vio.seek = sndSeek; + vio.read = sndRead; + vio.write = sndWrite; + vio.tell = sndTell; vio_data.length = 0; vio_data.offset = 0; vio_data.data = mStream; + vio_data.sampleBlockAlign = 1; + vio_data.byteBlockAlign = 0; + if ((sndFile = sf_open_virtual(&vio, SFM_READ, &sfinfo, &vio_data)) == NULL) { Con::printf("SFXSndStream - _readHeader failed: %s", sf_strerror(sndFile)); return false; } - S32 bitsPerSample = 0; - switch ((sfinfo.format & SF_FORMAT_SUBMASK)) + S32 bitsPerSample = 16; + + switch (sfinfo.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_PCM_S8: case SF_FORMAT_PCM_U8: bitsPerSample = 8; + mSampleType = Sample_Int8; // Still decode using sf_readf_short() break; + case SF_FORMAT_PCM_16: bitsPerSample = 16; + mSampleType = Sample_Int16; break; - case SF_FORMAT_VORBIS: + case SF_FORMAT_PCM_24: case SF_FORMAT_PCM_32: case SF_FORMAT_FLOAT: - bitsPerSample = 16; - sf_command(sndFile, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE); + case SF_FORMAT_DOUBLE: + case SF_FORMAT_VORBIS: + case SF_FORMAT_OPUS: + case SF_FORMAT_ALAC_20: + case SF_FORMAT_ALAC_24: + case SF_FORMAT_ALAC_32: + case 0x0080/*SF_FORMAT_MPEG_LAYER_I*/: + case 0x0081/*SF_FORMAT_MPEG_LAYER_II*/: + case 0x0082/*SF_FORMAT_MPEG_LAYER_III*/: + bitsPerSample = 32; + mSampleType = Sample_Float; break; - default: - // missed, set it to 16 anyway. + + case SF_FORMAT_IMA_ADPCM: bitsPerSample = 16; + mSampleType = Sample_IMA4; + break; + + case SF_FORMAT_MS_ADPCM: + bitsPerSample = 16; + mSampleType = Sample_MSADPCM; + break; + + default: + bitsPerSample = 16; + mSampleType = Sample_Int16; break; } - mFormat.set(sfinfo.channels, bitsPerSample * sfinfo.channels, sfinfo.samplerate); + //------------------------------------------------------------ + // Block alignment logic for ADPCM formats + //------------------------------------------------------------ + int byteBlockAlign = 0; + int sampleBlockAlign = 1; + + if (mSampleType == Sample_IMA4 || mSampleType == Sample_MSADPCM) + { + SF_CHUNK_INFO inf = { "fmt ", 4, 0, NULL }; + SF_CHUNK_ITERATOR* iter = sf_get_chunk_iterator(sndFile, &inf); + + if (!iter || sf_get_chunk_size(iter, &inf) != SF_ERR_NO_ERROR || inf.datalen < 14) + mSampleType = Sample_Int16; + else + { + uint8_t* fmtbuf = (uint8_t*)malloc(inf.datalen); + inf.data = fmtbuf; + + if (sf_get_chunk_data(iter, &inf) != SF_ERR_NO_ERROR) + mSampleType = Sample_Int16; + else + { + byteBlockAlign = fmtbuf[12] | (fmtbuf[13] << 8); + int ch = sfinfo.channels; + + if (mSampleType == Sample_IMA4) + sampleBlockAlign = (byteBlockAlign / ch - 4) / 4 * 8 + 1; + else + sampleBlockAlign = (byteBlockAlign / ch - 7) * 2 + 2; + } + dFree(fmtbuf); + } + } + + //------------------------------------------------------------ + // Commit alignment to class + VIO data + //------------------------------------------------------------ + if (mSampleType == Sample_Int16) + { + sampleBlockAlign = 1; + byteBlockAlign = sfinfo.channels * 2; + } + else if (mSampleType == Sample_Float) + { + sampleBlockAlign = 1; + byteBlockAlign = sfinfo.channels * 4; + } + + vio_data.sampleBlockAlign = sampleBlockAlign; + vio_data.byteBlockAlign = byteBlockAlign; + + mSampleBlockAlign = sampleBlockAlign; + mByteBlockAlign = byteBlockAlign; + + mFormat.set(sfinfo.channels, bitsPerSample * sfinfo.channels, sfinfo.samplerate, mSampleType); mSamples = sfinfo.frames; @@ -110,25 +191,32 @@ U32 SFXSndStream::read(U8* buffer, U32 length) return 0; } - U32 framesToRead = length / mFormat.getBytesPerSample(); + const U32 bytesPerFrame = mFormat.getBytesPerSample(); + U32 framesToRead = length / bytesPerFrame; + + // Enforce sample block alignment (important for ADPCM / compressed) + if (mSampleBlockAlign > 1) + framesToRead -= (framesToRead % mSampleBlockAlign); + + if (framesToRead == 0) + return 0; + U32 framesRead = 0; - switch (sfinfo.format & SF_FORMAT_SUBMASK) + switch (mSampleType) { - case SF_FORMAT_PCM_S8: - case SF_FORMAT_PCM_U8: - framesRead = sf_readf_int(sndFile, (int*)buffer, framesToRead); + case SFXSampleType::Sample_Int8: framesRead = sf_readf_int(sndFile, (int*)buffer, framesToRead); break; - case SF_FORMAT_PCM_16: - case SF_FORMAT_VORBIS: - case SF_FORMAT_PCM_24: - case SF_FORMAT_PCM_32: - case SF_FORMAT_FLOAT: - framesRead = sf_readf_short(sndFile, (short*)buffer, framesToRead); + case SFXSampleType::Sample_Int16: framesRead = sf_readf_short(sndFile, (short*)buffer, framesToRead); + break; + case SFXSampleType::Sample_Float: framesRead = sf_readf_float(sndFile, (float*)buffer, framesToRead); + break; + case SFXSampleType::Sample_IMA4: + case SFXSampleType::Sample_MSADPCM: + framesRead = sf_read_raw(sndFile, buffer, framesToRead); break; default: - Con::errorf("SFXSndStream - read: Unsupported format."); - return 0; + break; } if (framesRead != framesToRead) @@ -142,7 +230,6 @@ U32 SFXSndStream::read(U8* buffer, U32 length) // reset stream setPosition(0); } - return framesRead * mFormat.getBytesPerSample(); } @@ -221,4 +308,3 @@ sf_count_t SFXSndStream::sndFileLen(void* user_data) return vf->length; } - diff --git a/Engine/source/sfx/media/sfxSndStream.h b/Engine/source/sfx/media/sfxSndStream.h index a6bfbd28c..c190ab772 100644 --- a/Engine/source/sfx/media/sfxSndStream.h +++ b/Engine/source/sfx/media/sfxSndStream.h @@ -39,11 +39,18 @@ public: protected: + SFXSampleType mSampleType; + S32 mSampleBlockAlign; + S32 mByteBlockAlign; + // setup our vio_data struct. typedef struct { sf_count_t offset, length; Stream* data; + + S32 sampleBlockAlign; + S32 byteBlockAlign; } VIO_DATA; /// Total number of bytes read from the stream so far. @@ -58,11 +65,11 @@ protected: // vio callbacks static sf_count_t sndSeek(sf_count_t offset, int whence, void* user_data); - static sf_count_t sndRead(void *ptr, sf_count_t count, void* user_data); + static sf_count_t sndRead(void* ptr, sf_count_t count, void* user_data); static sf_count_t sndWrite(const void* ptr, sf_count_t count, void* user_data); static sf_count_t sndTell(void* user_data); static sf_count_t sndFileLen(void* user_data); - + // SFXStream bool _readHeader() override; void _close() override; diff --git a/Engine/source/sfx/null/sfxNullDevice.cpp b/Engine/source/sfx/null/sfxNullDevice.cpp index 6b53e29b7..9fc75573f 100644 --- a/Engine/source/sfx/null/sfxNullDevice.cpp +++ b/Engine/source/sfx/null/sfxNullDevice.cpp @@ -24,15 +24,30 @@ #include "sfx/null/sfxNullBuffer.h" #include "sfx/sfxInternal.h" - -SFXNullDevice::SFXNullDevice( SFXProvider* provider, - String name, - bool useHardware, - S32 maxBuffers ) - - : SFXDevice( name, provider, useHardware, maxBuffers ) +class SFXNULLRegisterProvider { - mMaxBuffers = getMax( maxBuffers, 8 ); +public: + SFXNULLRegisterProvider() + { + SFXSystem::getRegisterProviderSignal().notify(&SFXNullDevice::enumerateProviders); + } +}; + +static SFXNULLRegisterProvider pSFXNULLRegisterProvider; + + +SFXProvider::CreateProviderInstanceDelegate SFXNullDevice::mCreateDeviceInstance(SFXNullDevice::createInstance); + +SFXDevice* SFXNullDevice::createInstance(U32 providerIndex) +{ + SFXNullDevice* dev = new SFXNullDevice(providerIndex); + return dev; +} + + +SFXNullDevice::SFXNullDevice( U32 providerIndex ) +{ + mMaxBuffers = 8; } SFXNullDevice::~SFXNullDevice() @@ -65,6 +80,17 @@ SFXVoice* SFXNullDevice::createVoice( bool is3D, SFXBuffer *buffer ) return voice; } +void SFXNullDevice::enumerateProviders(Vector& providerList) +{ + SFXProvider* toAdd = new SFXProvider; + toAdd->mName = String::ToString("SFX Null Device"); + toAdd->mIndex = providerList.size(); + toAdd->mDeviceType = Output; + toAdd->mType = NullProvider; + toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance; + providerList.push_back(toAdd); +} + void SFXNullDevice::update() { // Do nothing. Prevent SFXDevice from running diff --git a/Engine/source/sfx/null/sfxNullDevice.h b/Engine/source/sfx/null/sfxNullDevice.h index 299b53cd8..d3b73a191 100644 --- a/Engine/source/sfx/null/sfxNullDevice.h +++ b/Engine/source/sfx/null/sfxNullDevice.h @@ -23,8 +23,6 @@ #ifndef _SFXNULLDEVICE_H_ #define _SFXNULLDEVICE_H_ -class SFXProvider; - #ifndef _SFXDEVICE_H_ #include "sfx/sfxDevice.h" #endif @@ -37,27 +35,28 @@ class SFXProvider; #ifndef _SFXNULLVOICE_H_ #include "sfx/null/sfxNullVoice.h" #endif - +#ifndef _SFXSYSTEM_H_ +#include "sfx/sfxSystem.h" +#endif class SFXNullDevice : public SFXDevice { typedef SFXDevice Parent; +protected: + static SFXProvider::CreateProviderInstanceDelegate mCreateDeviceInstance; - public: +public: + static void enumerateProviders(Vector& providerList); + SFXNullDevice( U32 providerIndex ); + static SFXDevice* createInstance(U32 adapterIndex); + virtual ~SFXNullDevice(); - SFXNullDevice( SFXProvider* provider, - String name, - bool useHardware, - S32 maxBuffers ); +public: - virtual ~SFXNullDevice(); - - public: - - // SFXDevice. - SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ) override; - SFXVoice* createVoice( bool is3D, SFXBuffer *buffer ) override; - void update() override; + // SFXDevice. + SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ) override; + SFXVoice* createVoice( bool is3D, SFXBuffer *buffer ) override; + void update() override; }; -#endif // _SFXNULLDEVICE_H_ \ No newline at end of file +#endif // _SFXNULLDEVICE_H_ diff --git a/Engine/source/sfx/null/sfxNullProvider.cpp b/Engine/source/sfx/null/sfxNullProvider.cpp deleted file mode 100644 index a41dda4c8..000000000 --- a/Engine/source/sfx/null/sfxNullProvider.cpp +++ /dev/null @@ -1,98 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "sfx/sfxProvider.h" -#include "sfx/null/sfxNullDevice.h" -#include "core/strings/stringFunctions.h" -#include "core/module.h" - - -class SFXNullProvider : public SFXProvider -{ -public: - - SFXNullProvider() - : SFXProvider( "Null" ) {} - virtual ~SFXNullProvider(); - -protected: - void addDeviceDesc( const String& name, const String& desc ); - void init() override; - -public: - - SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ) override; - -}; - -MODULE_BEGIN( SFXNull ) - - MODULE_INIT_BEFORE( SFX ) - MODULE_SHUTDOWN_AFTER( SFX ) - - SFXNullProvider* mProvider; - - MODULE_INIT - { - mProvider = new SFXNullProvider; - } - - MODULE_SHUTDOWN - { - delete mProvider; - } - -MODULE_END; - -void SFXNullProvider::init() -{ - regProvider( this ); - addDeviceDesc( "Null", "SFX Null Device" ); -} - -SFXNullProvider::~SFXNullProvider() -{ -} - - -void SFXNullProvider::addDeviceDesc( const String& name, const String& desc ) -{ - SFXDeviceInfo* info = new SFXDeviceInfo; - info->internalName = desc; - info->name = "Null Device"; - info->driver = name; - info->hasHardware = false; - info->maxBuffers = 8; - - mDeviceInfo.push_back( info ); -} - -SFXDevice* SFXNullProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ) -{ - SFXDeviceInfo* info = _findDeviceInfo( deviceName ); - - // Do we find one to create? - if ( info ) - return new SFXNullDevice( this, info->internalName, useHardware, maxBuffers ); - - return NULL; -} diff --git a/Engine/source/sfx/openal/LoadOAL.cpp b/Engine/source/sfx/openal/LoadOAL.cpp new file mode 100644 index 000000000..1f45aeb3b --- /dev/null +++ b/Engine/source/sfx/openal/LoadOAL.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2006, Creative Labs Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and + * the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the distribution. + * * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + // Based on Openal-soft router code. + +#include "sfx/openal/LoadOAL.h" +#include "console/console.h" + +#if defined(TORQUE_OS_WIN) +#include +#else +#include +#include +#endif + +LIB_HANDLE openaAlDll = NULL; + +#define LOAD_REQUIRED(table, x) \ + table->x = reinterpret_castx)>(reinterpret_cast( \ + GET_PROC_ADDRESS(openaAlDll, #x))); \ + if(!table->x) \ + { \ + Con::warnf("Failed to find entry point :%s\n", #x); \ + loadok = false; \ + } + + +ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE oal) +{ + if (!oal) + return AL_FALSE; + + if (szOALFullPathName) + openaAlDll = LOAD_LIBRARY(szOALFullPathName); + else + { +#if defined(TORQUE_OS_WIN) + openaAlDll = LOAD_LIBRARY("openal32.dll"); +#elif defined(TORQUE_OS_LINUX) + openaAlDll = LOAD_LIBRARY("libopenal.so"); +#elif defined(TORQUE_OS_MAC) + openaAlDll = LOAD_LIBRARY("@rpath/libopenal.1.24.3.dylib"); +#endif + } + + if (!openaAlDll) + return AL_FALSE; + + bool loadok = true; + + LOAD_REQUIRED(oal, alcCreateContext); + LOAD_REQUIRED(oal, alcMakeContextCurrent); + LOAD_REQUIRED(oal, alcProcessContext); + LOAD_REQUIRED(oal, alcSuspendContext); + LOAD_REQUIRED(oal, alcDestroyContext); + LOAD_REQUIRED(oal, alcGetCurrentContext); + LOAD_REQUIRED(oal, alcGetContextsDevice); + LOAD_REQUIRED(oal, alcOpenDevice); + LOAD_REQUIRED(oal, alcCloseDevice); + LOAD_REQUIRED(oal, alcGetError); + LOAD_REQUIRED(oal, alcIsExtensionPresent); + LOAD_REQUIRED(oal, alcGetProcAddress); + LOAD_REQUIRED(oal, alcGetEnumValue); + LOAD_REQUIRED(oal, alcGetString); + LOAD_REQUIRED(oal, alcGetIntegerv); + LOAD_REQUIRED(oal, alcCaptureOpenDevice); + LOAD_REQUIRED(oal, alcCaptureCloseDevice); + LOAD_REQUIRED(oal, alcCaptureStart); + LOAD_REQUIRED(oal, alcCaptureStop); + LOAD_REQUIRED(oal, alcCaptureSamples); + + LOAD_REQUIRED(oal, alEnable); + LOAD_REQUIRED(oal, alDisable); + LOAD_REQUIRED(oal, alIsEnabled); + LOAD_REQUIRED(oal, alGetString); + LOAD_REQUIRED(oal, alGetBooleanv); + LOAD_REQUIRED(oal, alGetIntegerv); + LOAD_REQUIRED(oal, alGetFloatv); + LOAD_REQUIRED(oal, alGetDoublev); + LOAD_REQUIRED(oal, alGetBoolean); + LOAD_REQUIRED(oal, alGetInteger); + LOAD_REQUIRED(oal, alGetFloat); + LOAD_REQUIRED(oal, alGetDouble); + LOAD_REQUIRED(oal, alGetError); + LOAD_REQUIRED(oal, alIsExtensionPresent); + LOAD_REQUIRED(oal, alGetProcAddress); + LOAD_REQUIRED(oal, alGetEnumValue); + LOAD_REQUIRED(oal, alListenerf); + LOAD_REQUIRED(oal, alListener3f); + LOAD_REQUIRED(oal, alListenerfv); + LOAD_REQUIRED(oal, alListeneri); + LOAD_REQUIRED(oal, alListener3i); + LOAD_REQUIRED(oal, alListeneriv); + LOAD_REQUIRED(oal, alGetListenerf); + LOAD_REQUIRED(oal, alGetListener3f); + LOAD_REQUIRED(oal, alGetListenerfv); + LOAD_REQUIRED(oal, alGetListeneri); + LOAD_REQUIRED(oal, alGetListener3i); + LOAD_REQUIRED(oal, alGetListeneriv); + LOAD_REQUIRED(oal, alGenSources); + LOAD_REQUIRED(oal, alDeleteSources); + LOAD_REQUIRED(oal, alIsSource); + LOAD_REQUIRED(oal, alSourcef); + LOAD_REQUIRED(oal, alSource3f); + LOAD_REQUIRED(oal, alSourcefv); + LOAD_REQUIRED(oal, alSourcei); + LOAD_REQUIRED(oal, alSource3i); + LOAD_REQUIRED(oal, alSourceiv); + LOAD_REQUIRED(oal, alGetSourcef); + LOAD_REQUIRED(oal, alGetSource3f); + LOAD_REQUIRED(oal, alGetSourcefv); + LOAD_REQUIRED(oal, alGetSourcei); + LOAD_REQUIRED(oal, alGetSource3i); + LOAD_REQUIRED(oal, alGetSourceiv); + LOAD_REQUIRED(oal, alSourcePlayv); + LOAD_REQUIRED(oal, alSourceStopv); + LOAD_REQUIRED(oal, alSourceRewindv); + LOAD_REQUIRED(oal, alSourcePausev); + LOAD_REQUIRED(oal, alSourcePlay); + LOAD_REQUIRED(oal, alSourceStop); + LOAD_REQUIRED(oal, alSourceRewind); + LOAD_REQUIRED(oal, alSourcePause); + LOAD_REQUIRED(oal, alSourceQueueBuffers); + LOAD_REQUIRED(oal, alSourceUnqueueBuffers); + LOAD_REQUIRED(oal, alGenBuffers); + LOAD_REQUIRED(oal, alDeleteBuffers); + LOAD_REQUIRED(oal, alIsBuffer); + LOAD_REQUIRED(oal, alBufferData); + LOAD_REQUIRED(oal, alDopplerFactor); + LOAD_REQUIRED(oal, alDopplerVelocity); + LOAD_REQUIRED(oal, alSpeedOfSound); + LOAD_REQUIRED(oal, alDistanceModel); + + // these are optional. + LOAD_REQUIRED(oal, alBufferf); + LOAD_REQUIRED(oal, alBuffer3f); + LOAD_REQUIRED(oal, alBufferfv); + LOAD_REQUIRED(oal, alBufferi); + LOAD_REQUIRED(oal, alBuffer3i); + LOAD_REQUIRED(oal, alBufferiv); + LOAD_REQUIRED(oal, alGetBufferf); + LOAD_REQUIRED(oal, alGetBuffer3f); + LOAD_REQUIRED(oal, alGetBufferfv); + LOAD_REQUIRED(oal, alGetBufferi); + LOAD_REQUIRED(oal, alGetBuffer3i); + LOAD_REQUIRED(oal, alGetBufferiv); + + return AL_TRUE; +} + +ALvoid UnloadOAL10Library() +{ + // Unload the dll + if (openaAlDll) + CLOSE_LIBRARY(openaAlDll); +} diff --git a/Engine/source/sfx/openal/LoadOAL.h b/Engine/source/sfx/openal/LoadOAL.h index dc9cc5de8..40495ae56 100644 --- a/Engine/source/sfx/openal/LoadOAL.h +++ b/Engine/source/sfx/openal/LoadOAL.h @@ -24,26 +24,52 @@ #define _LOADOAL_H_ #ifndef _PLATFORM_H_ -# include "platform/platform.h" +#include "platform/platform.h" #endif -#if defined(TORQUE_OS_MAC) -#undef AL_ALEXT_PROTOTYPES -# include -# include -#elif defined(TORQUE_OS_LINUX) -# include -# include -# include -# include -# include -#else -# include -# include -# include -# include +#ifndef _TVECTOR_H_ +#include "core/util/tVector.h" #endif +#ifndef _PATH_H_ +#include "core/util/path.h" +#endif + +// Since openal is deprecated and we pack the lib into the mac bundle, all +// platforms now support all of these. +#include +#include +#include +#include +#include + +#ifndef _OPENALFNTABLE +#define _OPENALFNTABLE + +#if defined(TORQUE_OS_WIN) +#include +#define LIB_HANDLE HINSTANCE +#define LOAD_LIBRARY(path) LoadLibraryA(path) +#define GET_PROC_ADDRESS(lib, name) GetProcAddress(lib, name) +#define CLOSE_LIBRARY(lib) FreeLibrary(lib) +#define LIB_EXTENSION L".dll" +#else +#include +#define LIB_HANDLE void* +#define LOAD_LIBRARY(path) dlopen(path, RTLD_LAZY) +#define GET_PROC_ADDRESS(lib, name) dlsym(lib, name) +#define CLOSE_LIBRARY(lib) dlclose(lib) +#ifdef __APPLE__ +#define LIB_EXTENSION ".dylib" +#else +#define LIB_EXTENSION ".so" +#endif +#endif + +constexpr auto MakeALCVer(int major, int minor) noexcept -> int { + return (major << 8) | minor; +} + #ifndef ALAPIENTRY #define ALAPIENTRY #endif @@ -52,11 +78,6 @@ #define ALCAPIENTRY #endif -// Open AL Function table definition - -#ifndef _OPENALFNTABLE -#define _OPENALFNTABLE - // AL 1.0 did not define the ALchar and ALCchar types, so define them here // if they don't exist @@ -68,110 +89,148 @@ #define ALCchar char #endif -typedef struct +struct OPENALFNTABLE { - LPALENABLE alEnable; - LPALDISABLE alDisable; - LPALISENABLED alIsEnabled; - LPALGETBOOLEAN alGetBoolean; - LPALGETINTEGER alGetInteger; - LPALGETFLOAT alGetFloat; - LPALGETDOUBLE alGetDouble; - LPALGETBOOLEANV alGetBooleanv; - LPALGETINTEGERV alGetIntegerv; - LPALGETFLOATV alGetFloatv; - LPALGETDOUBLEV alGetDoublev; - LPALGETSTRING alGetString; - LPALGETERROR alGetError; - LPALISEXTENSIONPRESENT alIsExtensionPresent; - LPALGETPROCADDRESS alGetProcAddress; - LPALGETENUMVALUE alGetEnumValue; - LPALLISTENERI alListeneri; - LPALLISTENERF alListenerf; - LPALLISTENER3F alListener3f; - LPALLISTENERFV alListenerfv; - LPALGETLISTENERI alGetListeneri; - LPALGETLISTENERF alGetListenerf; - LPALGETLISTENER3F alGetListener3f; - LPALGETLISTENERFV alGetListenerfv; - LPALGENSOURCES alGenSources; - LPALDELETESOURCES alDeleteSources; - LPALISSOURCE alIsSource; - LPALSOURCEI alSourcei; - LPALSOURCEF alSourcef; - LPALSOURCE3I alSource3i; - LPALSOURCE3F alSource3f; - LPALSOURCEFV alSourcefv; - LPALGETSOURCEI alGetSourcei; - LPALGETSOURCEF alGetSourcef; - LPALGETSOURCEFV alGetSourcefv; - LPALSOURCEPLAYV alSourcePlayv; - LPALSOURCESTOPV alSourceStopv; - LPALSOURCEPLAY alSourcePlay; - LPALSOURCEPAUSE alSourcePause; - LPALSOURCESTOP alSourceStop; - LPALSOURCEREWIND alSourceRewind; - LPALGENBUFFERS alGenBuffers; - LPALDELETEBUFFERS alDeleteBuffers; - LPALISBUFFER alIsBuffer; - LPALBUFFERDATA alBufferData; - LPALGETBUFFERI alGetBufferi; - LPALGETBUFFERF alGetBufferf; - LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers; - LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers; - LPALDISTANCEMODEL alDistanceModel; - LPALDOPPLERFACTOR alDopplerFactor; - LPALDOPPLERVELOCITY alDopplerVelocity; - LPALCGETSTRING alcGetString; - LPALCGETINTEGERV alcGetIntegerv; - LPALCOPENDEVICE alcOpenDevice; - LPALCCLOSEDEVICE alcCloseDevice; - LPALCCREATECONTEXT alcCreateContext; - LPALCMAKECONTEXTCURRENT alcMakeContextCurrent; - LPALCPROCESSCONTEXT alcProcessContext; - LPALCGETCURRENTCONTEXT alcGetCurrentContext; - LPALCGETCONTEXTSDEVICE alcGetContextsDevice; - LPALCSUSPENDCONTEXT alcSuspendContext; - LPALCDESTROYCONTEXT alcDestroyContext; - LPALCGETERROR alcGetError; - LPALCISEXTENSIONPRESENT alcIsExtensionPresent; - LPALCGETPROCADDRESS alcGetProcAddress; - LPALCGETENUMVALUE alcGetEnumValue; - -#if defined(AL_ALEXT_PROTOTYPES) - LPALGENEFFECTS alGenEffects; - LPALDELETEEFFECTS alDeleteEffects; - LPALISEFFECT alIsEffect; - LPALEFFECTI alEffecti; - LPALEFFECTIV alEffectiv; - LPALEFFECTF alEffectf; - LPALEFFECTFV alEffectfv; - LPALGETEFFECTI alGetEffecti; - LPALGETEFFECTIV alGetEffectiv; - LPALGETEFFECTF alGetEffectf; - LPALGETEFFECTFV alGetEffectfv; - LPALRELEASEALEFFECTS alReleaseEffects; - LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots; - LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots; - LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot; - LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti; - LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv; - LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf; - LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv; - LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti; - LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv; - LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf; - LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv; - LPALGENFILTERS alGenFilters; - LPALDELETEFILTERS alDeleteFilters; - LPALFILTERI alFilteri; - LPALCGETSTRINGISOFT alcGetStringiSOFT; + LPALCCREATECONTEXT alcCreateContext{ nullptr }; + LPALCMAKECONTEXTCURRENT alcMakeContextCurrent{ nullptr }; + LPALCPROCESSCONTEXT alcProcessContext{ nullptr }; + LPALCSUSPENDCONTEXT alcSuspendContext{ nullptr }; + LPALCDESTROYCONTEXT alcDestroyContext{ nullptr }; + LPALCGETCURRENTCONTEXT alcGetCurrentContext{ nullptr }; + LPALCGETCONTEXTSDEVICE alcGetContextsDevice{ nullptr }; + LPALCOPENDEVICE alcOpenDevice{ nullptr }; + LPALCCLOSEDEVICE alcCloseDevice{ nullptr }; + LPALCGETERROR alcGetError{ nullptr }; + LPALCISEXTENSIONPRESENT alcIsExtensionPresent{ nullptr }; + LPALCGETPROCADDRESS alcGetProcAddress{ nullptr }; + LPALCGETENUMVALUE alcGetEnumValue{ nullptr }; + LPALCGETSTRING alcGetString{ nullptr }; + LPALCGETINTEGERV alcGetIntegerv{ nullptr }; + LPALCCAPTUREOPENDEVICE alcCaptureOpenDevice{ nullptr }; + LPALCCAPTURECLOSEDEVICE alcCaptureCloseDevice{ nullptr }; + LPALCCAPTURESTART alcCaptureStart{ nullptr }; + LPALCCAPTURESTOP alcCaptureStop{ nullptr }; + LPALCCAPTURESAMPLES alcCaptureSamples{ nullptr }; + + PFNALCSETTHREADCONTEXTPROC alcSetThreadContext{ nullptr }; + PFNALCGETTHREADCONTEXTPROC alcGetThreadContext{ nullptr }; + + LPALENABLE alEnable{ nullptr }; + LPALDISABLE alDisable{ nullptr }; + LPALISENABLED alIsEnabled{ nullptr }; + LPALGETSTRING alGetString{ nullptr }; + LPALGETBOOLEANV alGetBooleanv{ nullptr }; + LPALGETINTEGERV alGetIntegerv{ nullptr }; + LPALGETFLOATV alGetFloatv{ nullptr }; + LPALGETDOUBLEV alGetDoublev{ nullptr }; + LPALGETBOOLEAN alGetBoolean{ nullptr }; + LPALGETINTEGER alGetInteger{ nullptr }; + LPALGETFLOAT alGetFloat{ nullptr }; + LPALGETDOUBLE alGetDouble{ nullptr }; + LPALGETERROR alGetError{ nullptr }; + LPALISEXTENSIONPRESENT alIsExtensionPresent{ nullptr }; + LPALGETPROCADDRESS alGetProcAddress{ nullptr }; + LPALGETENUMVALUE alGetEnumValue{ nullptr }; + LPALLISTENERF alListenerf{ nullptr }; + LPALLISTENER3F alListener3f{ nullptr }; + LPALLISTENERFV alListenerfv{ nullptr }; + LPALLISTENERI alListeneri{ nullptr }; + LPALLISTENER3I alListener3i{ nullptr }; + LPALLISTENERIV alListeneriv{ nullptr }; + LPALGETLISTENERF alGetListenerf{ nullptr }; + LPALGETLISTENER3F alGetListener3f{ nullptr }; + LPALGETLISTENERFV alGetListenerfv{ nullptr }; + LPALGETLISTENERI alGetListeneri{ nullptr }; + LPALGETLISTENER3I alGetListener3i{ nullptr }; + LPALGETLISTENERIV alGetListeneriv{ nullptr }; + LPALGENSOURCES alGenSources{ nullptr }; + LPALDELETESOURCES alDeleteSources{ nullptr }; + LPALISSOURCE alIsSource{ nullptr }; + LPALSOURCEF alSourcef{ nullptr }; + LPALSOURCE3F alSource3f{ nullptr }; + LPALSOURCEFV alSourcefv{ nullptr }; + LPALSOURCEI alSourcei{ nullptr }; + LPALSOURCE3I alSource3i{ nullptr }; + LPALSOURCEIV alSourceiv{ nullptr }; + LPALGETSOURCEF alGetSourcef{ nullptr }; + LPALGETSOURCE3F alGetSource3f{ nullptr }; + LPALGETSOURCEFV alGetSourcefv{ nullptr }; + LPALGETSOURCEI alGetSourcei{ nullptr }; + LPALGETSOURCE3I alGetSource3i{ nullptr }; + LPALGETSOURCEIV alGetSourceiv{ nullptr }; + LPALSOURCEPLAYV alSourcePlayv{ nullptr }; + LPALSOURCESTOPV alSourceStopv{ nullptr }; + LPALSOURCEREWINDV alSourceRewindv{ nullptr }; + LPALSOURCEPAUSEV alSourcePausev{ nullptr }; + LPALSOURCEPLAY alSourcePlay{ nullptr }; + LPALSOURCESTOP alSourceStop{ nullptr }; + LPALSOURCEREWIND alSourceRewind{ nullptr }; + LPALSOURCEPAUSE alSourcePause{ nullptr }; + LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers{ nullptr }; + LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers{ nullptr }; + LPALGENBUFFERS alGenBuffers{ nullptr }; + LPALDELETEBUFFERS alDeleteBuffers{ nullptr }; + LPALISBUFFER alIsBuffer{ nullptr }; + LPALBUFFERF alBufferf{ nullptr }; + LPALBUFFER3F alBuffer3f{ nullptr }; + LPALBUFFERFV alBufferfv{ nullptr }; + LPALBUFFERI alBufferi{ nullptr }; + LPALBUFFER3I alBuffer3i{ nullptr }; + LPALBUFFERIV alBufferiv{ nullptr }; + LPALGETBUFFERF alGetBufferf{ nullptr }; + LPALGETBUFFER3F alGetBuffer3f{ nullptr }; + LPALGETBUFFERFV alGetBufferfv{ nullptr }; + LPALGETBUFFERI alGetBufferi{ nullptr }; + LPALGETBUFFER3I alGetBuffer3i{ nullptr }; + LPALGETBUFFERIV alGetBufferiv{ nullptr }; + LPALBUFFERDATA alBufferData{ nullptr }; + LPALDOPPLERFACTOR alDopplerFactor{ nullptr }; + LPALDOPPLERVELOCITY alDopplerVelocity{ nullptr }; + LPALSPEEDOFSOUND alSpeedOfSound{ nullptr }; + LPALDISTANCEMODEL alDistanceModel{ nullptr }; + + /* Functions to load after first context creation. */ + LPALGENFILTERS alGenFilters{ nullptr }; + LPALDELETEFILTERS alDeleteFilters{ nullptr }; + LPALISFILTER alIsFilter{ nullptr }; + LPALFILTERF alFilterf{ nullptr }; + LPALFILTERFV alFilterfv{ nullptr }; + LPALFILTERI alFilteri{ nullptr }; + LPALFILTERIV alFilteriv{ nullptr }; + LPALGETFILTERF alGetFilterf{ nullptr }; + LPALGETFILTERFV alGetFilterfv{ nullptr }; + LPALGETFILTERI alGetFilteri{ nullptr }; + LPALGETFILTERIV alGetFilteriv{ nullptr }; + LPALGENEFFECTS alGenEffects{ nullptr }; + LPALDELETEEFFECTS alDeleteEffects{ nullptr }; + LPALISEFFECT alIsEffect{ nullptr }; + LPALEFFECTF alEffectf{ nullptr }; + LPALEFFECTFV alEffectfv{ nullptr }; + LPALEFFECTI alEffecti{ nullptr }; + LPALEFFECTIV alEffectiv{ nullptr }; + LPALGETEFFECTF alGetEffectf{ nullptr }; + LPALGETEFFECTFV alGetEffectfv{ nullptr }; + LPALGETEFFECTI alGetEffecti{ nullptr }; + LPALGETEFFECTIV alGetEffectiv{ nullptr }; + LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots{ nullptr }; + LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots{ nullptr }; + LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot{ nullptr }; + LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf{ nullptr }; + LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv{ nullptr }; + LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti{ nullptr }; + LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv{ nullptr }; + LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf{ nullptr }; + LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv{ nullptr }; + LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti{ nullptr }; + LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv{ nullptr }; + +}; + +using LPOPENALFNTABLE = OPENALFNTABLE*; + #endif -} OPENALFNTABLE, *LPOPENALFNTABLE; -#endif - -ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE lpOALFnTable); +ALboolean LoadOAL10Library(char* szOALFullPathName, LPOPENALFNTABLE lpOALFnTable); ALvoid UnloadOAL10Library(); #endif // _LOADOAL_H_ diff --git a/Engine/source/sfx/openal/aldlist.cpp b/Engine/source/sfx/openal/aldlist.cpp deleted file mode 100644 index f55a56569..000000000 --- a/Engine/source/sfx/openal/aldlist.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright (c) 2006, Creative Labs Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this list of conditions and - * the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions - * and the following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or - * promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "core/strings/stringFunctions.h" - -#include "aldlist.h" -#if defined(TORQUE_OS_MAC) -#include -#elif defined(TORQUE_OS_LINUX) -#include -#else -#include -#endif - - -/* - * Init call - */ -ALDeviceList::ALDeviceList( const OPENALFNTABLE& oalft ) -{ - VECTOR_SET_ASSOCIATION( vDeviceInfo ); - - ALDEVICEINFO ALDeviceInfo; - char *devices; - int index; - const char *defaultDeviceName; - const char *actualDeviceName; - - dMemcpy( &ALFunction, &oalft, sizeof(OPENALFNTABLE) ); - - // DeviceInfo vector stores, for each enumerated device, it's device name, selection status, spec version #, and extension support - vDeviceInfo.clear(); - vDeviceInfo.reserve(10); - - defaultDeviceIndex = 0; - - // grab function pointers for 1.0-API functions, and if successful proceed to enumerate all devices - if (ALFunction.alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT")) { - devices = (char *)ALFunction.alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); - defaultDeviceName = (char *)ALFunction.alcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER); - } - else - { - devices = (char *)ALFunction.alcGetString(NULL, ALC_DEVICE_SPECIFIER); - defaultDeviceName = (char *)ALFunction.alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); - } - - index = 0; - // go through device list (each device terminated with a single NULL, list terminated with double NULL) - while (*devices != '\0') { - if (String::compare(defaultDeviceName, devices) == 0) { - defaultDeviceIndex = index; - } - - ALCdevice* device = ALFunction.alcOpenDevice(devices); - if (device) - { - ALCcontext* ctx = ALFunction.alcCreateContext(device, nullptr); - - if (ctx) - { - ALFunction.alcMakeContextCurrent(ctx); - actualDeviceName = ALFunction.alcGetString(device, ALC_DEVICE_SPECIFIER); - bool bNewName = true; - - if (actualDeviceName) - { - for (int i = 0; i < GetNumDevices(); i++) { - if (String::compare(GetDeviceName(i), devices) == 0) { - bNewName = false; - } - } - } - - if ((bNewName) && (actualDeviceName != NULL) && (dStrlen(actualDeviceName) > 0)) - { - dMemset(&ALDeviceInfo, 0, sizeof(ALDEVICEINFO)); - ALDeviceInfo.bSelected = true; - dStrncpy(ALDeviceInfo.strDeviceName, actualDeviceName, sizeof(ALDeviceInfo.strDeviceName)); - char deviceExternal[256]; - dStrcpy(deviceExternal, devices, 256); - - vDeviceInfo.push_back(ALDeviceInfo); - } - - ALFunction.alcMakeContextCurrent(nullptr); - ALFunction.alcDestroyContext(ctx); - } - ALFunction.alcCloseDevice(device); - } - - devices += dStrlen(devices) + 1; - index += 1; - } - - ResetFilters(); -} - -/* - * Exit call - */ -ALDeviceList::~ALDeviceList() -{ -} - -/* - * Returns the number of devices in the complete device list - */ -int ALDeviceList::GetNumDevices() -{ - return (int)vDeviceInfo.size(); -} - -/* - * Returns the device name at an index in the complete device list - */ -const char* ALDeviceList::GetDeviceName(int index) -{ - if (index < GetNumDevices()) - return vDeviceInfo[index].strDeviceName; - else - return NULL; -} - - -/* - * Returns the major and minor version numbers for a device at a specified index in the complete list - */ -void ALDeviceList::GetDeviceVersion(int index, int *major, int *minor) -{ - if (index < GetNumDevices()) { - if (major) - *major = vDeviceInfo[index].iMajorVersion; - if (minor) - *minor = vDeviceInfo[index].iMinorVersion; - } - return; -} - -/* - * Returns the maximum number of Sources that can be generate on the given device - */ -U32 ALDeviceList::GetMaxNumSources(S32 index) -{ - if (index < GetNumDevices()) - return vDeviceInfo[index].uiSourceCount; - else - return 0; -} - -/* - * Checks if the extension is supported on the given device - */ -bool ALDeviceList::IsExtensionSupported(int index, SFXALCaps cap) -{ - bool bReturn = false; - - if (index < GetNumDevices()) - bReturn = vDeviceInfo[index].iCapsFlags & cap; - - return bReturn; -} - -/* - * returns the index of the default device in the complete device list - */ -int ALDeviceList::GetDefaultDevice() -{ - return defaultDeviceIndex; -} - -/* - * Deselects devices which don't have the specified minimum version - */ -void ALDeviceList::FilterDevicesMinVer(S32 major, S32 minor) -{ - int dMajor, dMinor; - for (U32 i = 0; i < vDeviceInfo.size(); i++) { - GetDeviceVersion(i, &dMajor, &dMinor); - if ((dMajor < major) || ((dMajor == major) && (dMinor < minor))) { - vDeviceInfo[i].bSelected = false; - } - } -} - -/* - * Deselects devices which don't have the specified maximum version - */ -void ALDeviceList::FilterDevicesMaxVer(S32 major, S32 minor) -{ - S32 dMajor, dMinor; - for (U32 i = 0; i < vDeviceInfo.size(); i++) { - GetDeviceVersion(i, &dMajor, &dMinor); - if ((dMajor > major) || ((dMajor == major) && (dMinor > minor))) { - vDeviceInfo[i].bSelected = false; - } - } -} - -/* - * Deselects device which don't support the given extension name - */ -void ALDeviceList::FilterDevicesExtension(SFXALCaps cap) -{ - for (U32 i = 0; i < vDeviceInfo.size(); i++) - vDeviceInfo[i].bSelected = vDeviceInfo[i].iCapsFlags & cap; -} - -/* - * Resets all filtering, such that all devices are in the list - */ -void ALDeviceList::ResetFilters() -{ - for (S32 i = 0; i < GetNumDevices(); i++) { - vDeviceInfo[i].bSelected = true; - } - filterIndex = 0; -} - -/* - * Gets index of first filtered device - */ -int ALDeviceList::GetFirstFilteredDevice() -{ - int i; - - for (i = 0; i < GetNumDevices(); i++) { - if (vDeviceInfo[i].bSelected == true) { - break; - } - } - filterIndex = i + 1; - return i; -} - -/* - * Gets index of next filtered device - */ -int ALDeviceList::GetNextFilteredDevice() -{ - int i; - - for (i = filterIndex; i < GetNumDevices(); i++) { - if (vDeviceInfo[i].bSelected == true) { - break; - } - } - filterIndex = i + 1; - return i; -} - -/* - * Internal function to detemine max number of Sources that can be generated - */ -unsigned int ALDeviceList::GetMaxNumSources() -{ - ALuint uiSources[256]; - U32 iSourceCount = 0; - - // Clear AL Error Code - ALFunction.alGetError(); - - // Generate up to 256 Sources, checking for any errors - for (iSourceCount = 0; iSourceCount < 256; iSourceCount++) - { - ALFunction.alGenSources(1, &uiSources[iSourceCount]); - if (ALFunction.alGetError() != AL_NO_ERROR) - break; - } - - // Release the Sources - ALFunction.alDeleteSources(iSourceCount, uiSources); - if (ALFunction.alGetError() != AL_NO_ERROR) - { - for (U32 i = 0; i < 256; i++) - { - ALFunction.alDeleteSources(1, &uiSources[i]); - } - } - - return iSourceCount; -} diff --git a/Engine/source/sfx/openal/aldlist.h b/Engine/source/sfx/openal/aldlist.h deleted file mode 100644 index 20f110361..000000000 --- a/Engine/source/sfx/openal/aldlist.h +++ /dev/null @@ -1,71 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef ALDEVICELIST_H -#define ALDEVICELIST_H - -#pragma warning(disable: 4786) //disable warning "identifier was truncated to '255' characters in the browser information" -#include "core/util/tVector.h" -#include "core/stringTable.h" -#include "sfx/openal/sfxALCaps.h" -#include "LoadOAL.h" - -typedef struct -{ - char strDeviceName[256]; - char strInternalDeviceName[256]; - S32 iMajorVersion; - S32 iMinorVersion; - U32 uiSourceCount; - S32 iCapsFlags; - bool bSelected; -} ALDEVICEINFO, *LPALDEVICEINFO; - -class ALDeviceList -{ -private: - OPENALFNTABLE ALFunction; - Vector vDeviceInfo; - S32 defaultDeviceIndex; - S32 filterIndex; - -public: - ALDeviceList ( const OPENALFNTABLE &oalft ); - ~ALDeviceList (); - S32 GetNumDevices(); - const char *GetDeviceName(S32 index); - void GetDeviceVersion(S32 index, S32 *major, S32 *minor); - U32 GetMaxNumSources(S32 index); - bool IsExtensionSupported(S32 index, SFXALCaps caps); - S32 GetDefaultDevice(); - void FilterDevicesMinVer(S32 major, S32 minor); - void FilterDevicesMaxVer(S32 major, S32 minor); - void FilterDevicesExtension(SFXALCaps caps); - void ResetFilters(); - S32 GetFirstFilteredDevice(); - S32 GetNextFilteredDevice(); - -private: - U32 GetMaxNumSources(); -}; - -#endif // ALDEVICELIST_H diff --git a/Engine/source/sfx/openal/linux/LoadOAL.linux.cpp b/Engine/source/sfx/openal/linux/LoadOAL.linux.cpp deleted file mode 100644 index 0ac1a59b3..000000000 --- a/Engine/source/sfx/openal/linux/LoadOAL.linux.cpp +++ /dev/null @@ -1,616 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -// TODO: Implement OpenAL loading code which is currently stubbed out. - -#if defined(__linux__) && !defined(TORQUE_OS_LINUX) -#define TORQUE_OS_LINUX -#endif - -#include -#include -#include -#include "sfx/openal/LoadOAL.h" -#include "console/console.h" - -void* openal_library = NULL; - -ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE lpOALFnTable) -{ - if (!lpOALFnTable) - return AL_FALSE; - - if (szOALFullPathName) - openal_library = dlopen(szOALFullPathName, RTLD_NOW); - else - { -#ifdef TORQUE_DEBUG - openal_library = dlopen("libopenald.so.1", RTLD_NOW); - - // If the .1 library is not found, try the normal filename - if (openal_library == NULL) - { - openal_library = dlopen("libopenald.so", RTLD_NOW); - } -#else - openal_library = dlopen("libopenal.so.1", RTLD_NOW); - - // If the .1 library is not found, try the normal filename - if (openal_library == NULL) - { - openal_library = dlopen("libopenal.so", RTLD_NOW); - } -#endif - } - - if (openal_library == NULL) { - Con::errorf("Failed to load OpenAL shared library. Sound will not be available"); - return AL_FALSE; - } - - memset(lpOALFnTable, 0, sizeof(OPENALFNTABLE)); - - lpOALFnTable->alEnable = (LPALENABLE)dlsym(openal_library,"alEnable"); - if (lpOALFnTable->alEnable == NULL) - { - warn("Failed to retrieve 'alEnable' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDisable = (LPALDISABLE)dlsym(openal_library,"alDisable"); - if (lpOALFnTable->alDisable == NULL) - { - warn("Failed to retrieve 'alDisable' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsEnabled = (LPALISENABLED)dlsym(openal_library,"alIsEnabled"); - if (lpOALFnTable->alIsEnabled == NULL) - { - warn("Failed to retrieve 'alIsEnabled' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBoolean = (LPALGETBOOLEAN)dlsym(openal_library,"alGetBoolean"); - if (lpOALFnTable->alGetBoolean == NULL) - { - warn("Failed to retrieve 'alGetBoolean' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetInteger = (LPALGETINTEGER)dlsym(openal_library,"alGetInteger"); - if (lpOALFnTable->alGetInteger == NULL) - { - warn("Failed to retrieve 'alGetInteger' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetFloat = (LPALGETFLOAT)dlsym(openal_library,"alGetFloat"); - if (lpOALFnTable->alGetFloat == NULL) - { - warn("Failed to retrieve 'alGetFloat' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetDouble = (LPALGETDOUBLE)dlsym(openal_library,"alGetDouble"); - if (lpOALFnTable->alGetDouble == NULL) - { - warn("Failed to retrieve 'alGetDouble' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBooleanv = (LPALGETBOOLEANV)dlsym(openal_library,"alGetBooleanv"); - if (lpOALFnTable->alGetBooleanv == NULL) - { - warn("Failed to retrieve 'alGetBooleanv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetIntegerv = (LPALGETINTEGERV)dlsym(openal_library,"alGetIntegerv"); - if (lpOALFnTable->alGetIntegerv == NULL) - { - warn("Failed to retrieve 'alGetIntegerv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetFloatv = (LPALGETFLOATV)dlsym(openal_library,"alGetFloatv"); - if (lpOALFnTable->alGetFloatv == NULL) - { - warn("Failed to retrieve 'alGetFloatv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetDoublev = (LPALGETDOUBLEV)dlsym(openal_library,"alGetDoublev"); - if (lpOALFnTable->alGetDoublev == NULL) - { - warn("Failed to retrieve 'alGetDoublev' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetString = (LPALGETSTRING)dlsym(openal_library,"alGetString"); - if (lpOALFnTable->alGetString == NULL) - { - warn("Failed to retrieve 'alGetString' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetError = (LPALGETERROR)dlsym(openal_library,"alGetError"); - if (lpOALFnTable->alGetError == NULL) - { - warn("Failed to retrieve 'alGetError' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsExtensionPresent = (LPALISEXTENSIONPRESENT)dlsym(openal_library,"alIsExtensionPresent"); - if (lpOALFnTable->alIsExtensionPresent == NULL) - { - warn("Failed to retrieve 'alIsExtensionPresent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetProcAddress = (LPALGETPROCADDRESS)dlsym(openal_library,"alGetProcAddress"); - if (lpOALFnTable->alGetProcAddress == NULL) - { - warn("Failed to retrieve 'alGetProcAddress' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEnumValue = (LPALGETENUMVALUE)dlsym(openal_library,"alGetEnumValue"); - if (lpOALFnTable->alGetEnumValue == NULL) - { - warn("Failed to retrieve 'alGetEnumValue' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListeneri = (LPALLISTENERI)dlsym(openal_library,"alListeneri"); - if (lpOALFnTable->alListeneri == NULL) - { - warn("Failed to retrieve 'alListeneri' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListenerf = (LPALLISTENERF)dlsym(openal_library,"alListenerf"); - if (lpOALFnTable->alListenerf == NULL) - { - warn("Failed to retrieve 'alListenerf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListener3f = (LPALLISTENER3F)dlsym(openal_library,"alListener3f"); - if (lpOALFnTable->alListener3f == NULL) - { - warn("Failed to retrieve 'alListener3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListenerfv = (LPALLISTENERFV)dlsym(openal_library,"alListenerfv"); - if (lpOALFnTable->alListenerfv == NULL) - { - warn("Failed to retrieve 'alListenerfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListeneri = (LPALGETLISTENERI)dlsym(openal_library,"alGetListeneri"); - if (lpOALFnTable->alGetListeneri == NULL) - { - warn("Failed to retrieve 'alGetListeneri' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListenerf =(LPALGETLISTENERF)dlsym(openal_library,"alGetListenerf"); - if (lpOALFnTable->alGetListenerf == NULL) - { - warn("Failed to retrieve 'alGetListenerf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListener3f = (LPALGETLISTENER3F)dlsym(openal_library,"alGetListener3f"); - if (lpOALFnTable->alGetListener3f == NULL) - { - warn("Failed to retrieve 'alGetListener3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListenerfv = (LPALGETLISTENERFV)dlsym(openal_library,"alGetListenerfv"); - if (lpOALFnTable->alGetListenerfv == NULL) - { - warn("Failed to retrieve 'alGetListenerfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGenSources = (LPALGENSOURCES)dlsym(openal_library,"alGenSources"); - if (lpOALFnTable->alGenSources == NULL) - { - warn("Failed to retrieve 'alGenSources' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteSources = (LPALDELETESOURCES)dlsym(openal_library,"alDeleteSources"); - if (lpOALFnTable->alDeleteSources == NULL) - { - warn("Failed to retrieve 'alDeleteSources' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsSource = (LPALISSOURCE)dlsym(openal_library,"alIsSource"); - if (lpOALFnTable->alIsSource == NULL) - { - warn("Failed to retrieve 'alIsSource' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcei = (LPALSOURCEI)dlsym(openal_library,"alSourcei"); - if (lpOALFnTable->alSourcei == NULL) - { - warn("Failed to retrieve 'alSourcei' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcef = (LPALSOURCEF)dlsym(openal_library,"alSourcef"); - if (lpOALFnTable->alSourcef == NULL) - { - warn("Failed to retrieve 'alSourcef' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSource3f = (LPALSOURCE3F)dlsym(openal_library,"alSource3f"); - if (lpOALFnTable->alSource3f == NULL) - { - warn("Failed to retrieve 'alSource3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcefv = (LPALSOURCEFV)dlsym(openal_library,"alSourcefv"); - if (lpOALFnTable->alSourcefv == NULL) - { - warn("Failed to retrieve 'alSourcefv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcei = (LPALGETSOURCEI)dlsym(openal_library,"alGetSourcei"); - if (lpOALFnTable->alGetSourcei == NULL) - { - warn("Failed to retrieve 'alGetSourcei' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcef = (LPALGETSOURCEF)dlsym(openal_library,"alGetSourcef"); - if (lpOALFnTable->alGetSourcef == NULL) - { - warn("Failed to retrieve 'alGetSourcef' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcefv = (LPALGETSOURCEFV)dlsym(openal_library,"alGetSourcefv"); - if (lpOALFnTable->alGetSourcefv == NULL) - { - warn("Failed to retrieve 'alGetSourcefv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePlayv = (LPALSOURCEPLAYV)dlsym(openal_library,"alSourcePlayv"); - if (lpOALFnTable->alSourcePlayv == NULL) - { - warn("Failed to retrieve 'alSourcePlayv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceStopv = (LPALSOURCESTOPV)dlsym(openal_library,"alSourceStopv"); - if (lpOALFnTable->alSourceStopv == NULL) - { - warn("Failed to retrieve 'alSourceStopv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePlay = (LPALSOURCEPLAY)dlsym(openal_library,"alSourcePlay"); - if (lpOALFnTable->alSourcePlay == NULL) - { - warn("Failed to retrieve 'alSourcePlay' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePause = (LPALSOURCEPAUSE)dlsym(openal_library,"alSourcePause"); - if (lpOALFnTable->alSourcePause == NULL) - { - warn("Failed to retrieve 'alSourcePause' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceStop = (LPALSOURCESTOP)dlsym(openal_library,"alSourceStop"); - if (lpOALFnTable->alSourceStop == NULL) - { - warn("Failed to retrieve 'alSourceStop' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceRewind = (LPALSOURCEREWIND)dlsym(openal_library,"alSourceRewind"); - if (lpOALFnTable->alSourceRewind == NULL) - { - warn("Failed to retrieve 'alSourceRewind' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGenBuffers = (LPALGENBUFFERS)dlsym(openal_library,"alGenBuffers"); - if (lpOALFnTable->alGenBuffers == NULL) - { - warn("Failed to retrieve 'alGenBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteBuffers = (LPALDELETEBUFFERS)dlsym(openal_library,"alDeleteBuffers"); - if (lpOALFnTable->alDeleteBuffers == NULL) - { - warn("Failed to retrieve 'alDeleteBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsBuffer = (LPALISBUFFER)dlsym(openal_library,"alIsBuffer"); - if (lpOALFnTable->alIsBuffer == NULL) - { - warn("Failed to retrieve 'alIsBuffer' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alBufferData = (LPALBUFFERDATA)dlsym(openal_library,"alBufferData"); - if (lpOALFnTable->alBufferData == NULL) - { - warn("Failed to retrieve 'alBufferData' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBufferi = (LPALGETBUFFERI)dlsym(openal_library,"alGetBufferi"); - if (lpOALFnTable->alGetBufferi == NULL) - { - warn("Failed to retrieve 'alGetBufferi' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBufferf = (LPALGETBUFFERF)dlsym(openal_library,"alGetBufferf"); - if (lpOALFnTable->alGetBufferf == NULL) - { - warn("Failed to retrieve 'alGetBufferf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceQueueBuffers = (LPALSOURCEQUEUEBUFFERS)dlsym(openal_library,"alSourceQueueBuffers"); - if (lpOALFnTable->alSourceQueueBuffers == NULL) - { - warn("Failed to retrieve 'alSourceQueueBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceUnqueueBuffers = (LPALSOURCEUNQUEUEBUFFERS)dlsym(openal_library,"alSourceUnqueueBuffers"); - if (lpOALFnTable->alSourceUnqueueBuffers == NULL) - { - warn("Failed to retrieve 'alSourceUnqueueBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDistanceModel = (LPALDISTANCEMODEL)dlsym(openal_library,"alDistanceModel"); - if (lpOALFnTable->alDistanceModel == NULL) - { - warn("Failed to retrieve 'alDistanceModel' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDopplerFactor = (LPALDOPPLERFACTOR)dlsym(openal_library,"alDopplerFactor"); - if (lpOALFnTable->alDopplerFactor == NULL) - { - warn("Failed to retrieve 'alDopplerFactor' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDopplerVelocity = (LPALDOPPLERVELOCITY)dlsym(openal_library,"alDopplerVelocity"); - if (lpOALFnTable->alDopplerVelocity == NULL) - { - warn("Failed to retrieve 'alDopplerVelocity' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetString = (LPALCGETSTRING)dlsym(openal_library,"alcGetString"); - if (lpOALFnTable->alcGetString == NULL) - { - warn("Failed to retrieve 'alcGetString' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetIntegerv = (LPALCGETINTEGERV)dlsym(openal_library,"alcGetIntegerv"); - if (lpOALFnTable->alcGetIntegerv == NULL) - { - warn("Failed to retrieve 'alcGetIntegerv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcOpenDevice = (LPALCOPENDEVICE)dlsym(openal_library,"alcOpenDevice"); - if (lpOALFnTable->alcOpenDevice == NULL) - { - warn("Failed to retrieve 'alcOpenDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcCloseDevice = (LPALCCLOSEDEVICE)dlsym(openal_library,"alcCloseDevice"); - if (lpOALFnTable->alcCloseDevice == NULL) - { - warn("Failed to retrieve 'alcCloseDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcCreateContext = (LPALCCREATECONTEXT)dlsym(openal_library,"alcCreateContext"); - if (lpOALFnTable->alcCreateContext == NULL) - { - warn("Failed to retrieve 'alcCreateContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcMakeContextCurrent = (LPALCMAKECONTEXTCURRENT)dlsym(openal_library,"alcMakeContextCurrent"); - if (lpOALFnTable->alcMakeContextCurrent == NULL) - { - warn("Failed to retrieve 'alcMakeContextCurrent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcProcessContext = (LPALCPROCESSCONTEXT)dlsym(openal_library,"alcProcessContext"); - if (lpOALFnTable->alcProcessContext == NULL) - { - warn("Failed to retrieve 'alcProcessContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetCurrentContext = (LPALCGETCURRENTCONTEXT)dlsym(openal_library,"alcGetCurrentContext"); - if (lpOALFnTable->alcGetCurrentContext == NULL) - { - warn("Failed to retrieve 'alcGetCurrentContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetContextsDevice = (LPALCGETCONTEXTSDEVICE)dlsym(openal_library,"alcGetContextsDevice"); - if (lpOALFnTable->alcGetContextsDevice == NULL) - { - warn("Failed to retrieve 'alcGetContextsDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcSuspendContext = (LPALCSUSPENDCONTEXT)dlsym(openal_library,"alcSuspendContext"); - if (lpOALFnTable->alcSuspendContext == NULL) - { - warn("Failed to retrieve 'alcSuspendContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcDestroyContext = (LPALCDESTROYCONTEXT)dlsym(openal_library,"alcDestroyContext"); - if (lpOALFnTable->alcDestroyContext == NULL) - { - warn("Failed to retrieve 'alcDestroyContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetError = (LPALCGETERROR)dlsym(openal_library,"alcGetError"); - if (lpOALFnTable->alcGetError == NULL) - { - warn("Failed to retrieve 'alcGetError' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcIsExtensionPresent = (LPALCISEXTENSIONPRESENT)dlsym(openal_library,"alcIsExtensionPresent"); - if (lpOALFnTable->alcIsExtensionPresent == NULL) - { - warn("Failed to retrieve 'alcIsExtensionPresent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetProcAddress = (LPALCGETPROCADDRESS)dlsym(openal_library,"alcGetProcAddress"); - if (lpOALFnTable->alcGetProcAddress == NULL) - { - warn("Failed to retrieve 'alcGetProcAddress' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetEnumValue = (LPALCGETENUMVALUE)dlsym(openal_library,"alcGetEnumValue"); - if (lpOALFnTable->alcGetEnumValue == NULL) - { - warn("Failed to retrieve 'alcGetEnumValue' function address\n"); - return AL_FALSE; - } -#if defined(AL_ALEXT_PROTOTYPES) - //efx - lpOALFnTable->alGenEffects = (LPALGENEFFECTS)dlsym(openal_library, "alGenEffects"); - if (lpOALFnTable->alGenEffects == NULL) - { - warn("Failed to retrieve 'alGenEffects' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alEffecti = (LPALEFFECTI)dlsym(openal_library, "alEffecti"); - if (lpOALFnTable->alEffecti == NULL) - { - warn("Failed to retrieve 'alEffecti' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alEffectiv = (LPALEFFECTIV)dlsym(openal_library, "alEffectiv"); - if (lpOALFnTable->alEffectiv == NULL) - { - warn("Failed to retrieve 'alEffectiv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alEffectf = (LPALEFFECTF)dlsym(openal_library, "alEffectf"); - if (lpOALFnTable->alEffectf == NULL) - { - warn("Failed to retrieve 'alEffectf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alEffectfv = (LPALEFFECTFV)dlsym(openal_library, "alEffectfv"); - if (lpOALFnTable->alEffectfv == NULL) - { - warn("Failed to retrieve 'alEffectfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEffecti = (LPALGETEFFECTI)dlsym(openal_library, "alGetEffecti"); - if (lpOALFnTable->alGetEffecti == NULL) - { - warn("Failed to retrieve 'alGetEffecti' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEffectiv = (LPALGETEFFECTIV)dlsym(openal_library, "alGetEffectiv"); - if (lpOALFnTable->alGetEffectiv == NULL) - { - warn("Failed to retrieve 'alGetEffectiv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEffectf = (LPALGETEFFECTF)dlsym(openal_library, "alGetEffectf"); - if (lpOALFnTable->alGetEffectf == NULL) - { - warn("Failed to retrieve 'alGetEffectf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEffectfv = (LPALGETEFFECTFV)dlsym(openal_library, "alGetEffectfv"); - if (lpOALFnTable->alGetEffectfv == NULL) - { - warn("Failed to retrieve 'alGetEffectfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteEffects = (LPALDELETEEFFECTS)dlsym(openal_library, "alDeleteEffects"); - if (lpOALFnTable->alDeleteEffects == NULL) - { - warn("Failed to retrieve 'alDeleteEffects' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsEffect = (LPALISEFFECT)dlsym(openal_library, "alIsEffect"); - if (lpOALFnTable->alIsEffect == NULL) - { - warn("Failed to retrieve 'alIsEffect' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alAuxiliaryEffectSlotf = (LPALAUXILIARYEFFECTSLOTF)dlsym(openal_library, "alAuxiliaryEffectSlotf"); - if (lpOALFnTable->alAuxiliaryEffectSlotf == NULL) - { - warn("Failed to retrieve 'alAuxiliaryEffectSlotf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alAuxiliaryEffectSlotfv = (LPALAUXILIARYEFFECTSLOTFV)dlsym(openal_library, "alAuxiliaryEffectSlotfv"); - if (lpOALFnTable->alAuxiliaryEffectSlotfv == NULL) - { - warn("Failed to retrieve 'alAuxiliaryEffectSlotfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)dlsym(openal_library, "alAuxiliaryEffectSloti"); - if (lpOALFnTable->alAuxiliaryEffectSloti == NULL) - { - warn("Failed to retrieve 'alAuxiliaryEffectSloti' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alAuxiliaryEffectSlotiv = (LPALAUXILIARYEFFECTSLOTIV)dlsym(openal_library, "alAuxiliaryEffectSlotiv"); - if (lpOALFnTable->alAuxiliaryEffectSlotiv == NULL) - { - warn("Failed to retrieve 'alAuxiliaryEffectSlotiv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)dlsym(openal_library, "alIsAuxiliaryEffectSlot"); - if (lpOALFnTable->alIsAuxiliaryEffectSlot == NULL) - { - warn("Failed to retrieve 'alIsAuxiliaryEffectSlot' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)dlsym(openal_library, "alGenAuxiliaryEffectSlots"); - if (lpOALFnTable->alGenAuxiliaryEffectSlots == NULL) - { - warn("Failed to retrieve 'alGenAuxiliaryEffectSlots' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)dlsym(openal_library, "alDeleteAuxiliaryEffectSlots"); - if (lpOALFnTable->alDeleteAuxiliaryEffectSlots == NULL) - { - warn("Failed to retrieve 'alDeleteAuxiliaryEffectSlots' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetAuxiliaryEffectSlotf = (LPALGETAUXILIARYEFFECTSLOTF)dlsym(openal_library, "alGetAuxiliaryEffectSlotf"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotf == NULL) - { - warn("Failed to retrieve 'alGetAuxiliaryEffectSlotf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetAuxiliaryEffectSlotfv = (LPALGETAUXILIARYEFFECTSLOTFV)dlsym(openal_library, "alGetAuxiliaryEffectSlotfv"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotfv == NULL) - { - warn("Failed to retrieve 'alGetAuxiliaryEffectSlotfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetAuxiliaryEffectSloti = (LPALGETAUXILIARYEFFECTSLOTI)dlsym(openal_library, "alGetAuxiliaryEffectSloti"); - if (lpOALFnTable->alGetAuxiliaryEffectSloti == NULL) - { - warn("Failed to retrieve 'alGetAuxiliaryEffectSloti' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetAuxiliaryEffectSlotiv = (LPALGETAUXILIARYEFFECTSLOTIV)dlsym(openal_library, "alGetAuxiliaryEffectSlotiv"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotiv == NULL) - { - warn("Failed to retrieve 'alGetAuxiliaryEffectSlotiv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSource3i = (LPALSOURCE3I)dlsym(openal_library, "alSource3i"); - if (lpOALFnTable->alSource3i == NULL) - { - warn("Failed to retrieve 'alSource3i' function address\n"); - return AL_FALSE; - } -#endif - return AL_TRUE; -} - -ALvoid UnloadOAL10Library() -{ - if (openal_library != NULL) - dlclose(openal_library); -} diff --git a/Engine/source/sfx/openal/mac/LoadOAL.mac.cpp b/Engine/source/sfx/openal/mac/LoadOAL.mac.cpp deleted file mode 100644 index baf40d33b..000000000 --- a/Engine/source/sfx/openal/mac/LoadOAL.mac.cpp +++ /dev/null @@ -1,618 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -// TODO: Implement OpenAL loading code which is currently stubbed out. - -#if defined(__MACOSX__) && !defined(TORQUE_OS_MAC) -#define TORQUE_OS_MAC -#endif - -#include "console/console.h" - -#include -#include -#include -#include "sfx/openal/LoadOAL.h" - -void* openal_library = NULL; - -ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE lpOALFnTable) -{ - // TODO: Implement this. - if (!lpOALFnTable) - return AL_FALSE; - - if (szOALFullPathName) - openal_library = dlopen(szOALFullPathName, RTLD_NOW); - else - { -#ifdef TORQUE_DEBUG - openal_library = dlopen("@rpath/libopenald.1.23.1.dylib", RTLD_NOW); - - if (openal_library == NULL) - { - openal_library = dlopen("@rpath/libopenald.1.dylib", RTLD_NOW); - } -#else - openal_library = dlopen("@rpath/libopenal.1.23.1.dylib", RTLD_NOW); - - if (openal_library == NULL) - { - openal_library = dlopen("@rpath/libopenal .1.dylib", RTLD_NOW); - } -#endif - } - - if (openal_library == NULL) - { - Con::errorf("Failed to load OpenAL shared library. Sound will not be available"); - return AL_FALSE; - } - - - memset(lpOALFnTable, 0, sizeof(OPENALFNTABLE)); - - lpOALFnTable->alEnable = (LPALENABLE)dlsym(openal_library,"alEnable"); - if (lpOALFnTable->alEnable == NULL) - { - warn("Failed to retrieve 'alEnable' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDisable = (LPALDISABLE)dlsym(openal_library,"alDisable"); - if (lpOALFnTable->alDisable == NULL) - { - warn("Failed to retrieve 'alDisable' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsEnabled = (LPALISENABLED)dlsym(openal_library,"alIsEnabled"); - if (lpOALFnTable->alIsEnabled == NULL) - { - warn("Failed to retrieve 'alIsEnabled' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBoolean = (LPALGETBOOLEAN)dlsym(openal_library,"alGetBoolean"); - if (lpOALFnTable->alGetBoolean == NULL) - { - warn("Failed to retrieve 'alGetBoolean' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetInteger = (LPALGETINTEGER)dlsym(openal_library,"alGetInteger"); - if (lpOALFnTable->alGetInteger == NULL) - { - warn("Failed to retrieve 'alGetInteger' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetFloat = (LPALGETFLOAT)dlsym(openal_library,"alGetFloat"); - if (lpOALFnTable->alGetFloat == NULL) - { - warn("Failed to retrieve 'alGetFloat' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetDouble = (LPALGETDOUBLE)dlsym(openal_library,"alGetDouble"); - if (lpOALFnTable->alGetDouble == NULL) - { - warn("Failed to retrieve 'alGetDouble' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBooleanv = (LPALGETBOOLEANV)dlsym(openal_library,"alGetBooleanv"); - if (lpOALFnTable->alGetBooleanv == NULL) - { - warn("Failed to retrieve 'alGetBooleanv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetIntegerv = (LPALGETINTEGERV)dlsym(openal_library,"alGetIntegerv"); - if (lpOALFnTable->alGetIntegerv == NULL) - { - warn("Failed to retrieve 'alGetIntegerv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetFloatv = (LPALGETFLOATV)dlsym(openal_library,"alGetFloatv"); - if (lpOALFnTable->alGetFloatv == NULL) - { - warn("Failed to retrieve 'alGetFloatv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetDoublev = (LPALGETDOUBLEV)dlsym(openal_library,"alGetDoublev"); - if (lpOALFnTable->alGetDoublev == NULL) - { - warn("Failed to retrieve 'alGetDoublev' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetString = (LPALGETSTRING)dlsym(openal_library,"alGetString"); - if (lpOALFnTable->alGetString == NULL) - { - warn("Failed to retrieve 'alGetString' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetError = (LPALGETERROR)dlsym(openal_library,"alGetError"); - if (lpOALFnTable->alGetError == NULL) - { - warn("Failed to retrieve 'alGetError' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsExtensionPresent = (LPALISEXTENSIONPRESENT)dlsym(openal_library,"alIsExtensionPresent"); - if (lpOALFnTable->alIsExtensionPresent == NULL) - { - warn("Failed to retrieve 'alIsExtensionPresent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetProcAddress = (LPALGETPROCADDRESS)dlsym(openal_library,"alGetProcAddress"); - if (lpOALFnTable->alGetProcAddress == NULL) - { - warn("Failed to retrieve 'alGetProcAddress' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEnumValue = (LPALGETENUMVALUE)dlsym(openal_library,"alGetEnumValue"); - if (lpOALFnTable->alGetEnumValue == NULL) - { - warn("Failed to retrieve 'alGetEnumValue' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListeneri = (LPALLISTENERI)dlsym(openal_library,"alListeneri"); - if (lpOALFnTable->alListeneri == NULL) - { - warn("Failed to retrieve 'alListeneri' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListenerf = (LPALLISTENERF)dlsym(openal_library,"alListenerf"); - if (lpOALFnTable->alListenerf == NULL) - { - warn("Failed to retrieve 'alListenerf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListener3f = (LPALLISTENER3F)dlsym(openal_library,"alListener3f"); - if (lpOALFnTable->alListener3f == NULL) - { - warn("Failed to retrieve 'alListener3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListenerfv = (LPALLISTENERFV)dlsym(openal_library,"alListenerfv"); - if (lpOALFnTable->alListenerfv == NULL) - { - warn("Failed to retrieve 'alListenerfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListeneri = (LPALGETLISTENERI)dlsym(openal_library,"alGetListeneri"); - if (lpOALFnTable->alGetListeneri == NULL) - { - warn("Failed to retrieve 'alGetListeneri' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListenerf =(LPALGETLISTENERF)dlsym(openal_library,"alGetListenerf"); - if (lpOALFnTable->alGetListenerf == NULL) - { - warn("Failed to retrieve 'alGetListenerf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListener3f = (LPALGETLISTENER3F)dlsym(openal_library,"alGetListener3f"); - if (lpOALFnTable->alGetListener3f == NULL) - { - warn("Failed to retrieve 'alGetListener3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListenerfv = (LPALGETLISTENERFV)dlsym(openal_library,"alGetListenerfv"); - if (lpOALFnTable->alGetListenerfv == NULL) - { - warn("Failed to retrieve 'alGetListenerfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGenSources = (LPALGENSOURCES)dlsym(openal_library,"alGenSources"); - if (lpOALFnTable->alGenSources == NULL) - { - warn("Failed to retrieve 'alGenSources' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteSources = (LPALDELETESOURCES)dlsym(openal_library,"alDeleteSources"); - if (lpOALFnTable->alDeleteSources == NULL) - { - warn("Failed to retrieve 'alDeleteSources' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsSource = (LPALISSOURCE)dlsym(openal_library,"alIsSource"); - if (lpOALFnTable->alIsSource == NULL) - { - warn("Failed to retrieve 'alIsSource' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcei = (LPALSOURCEI)dlsym(openal_library,"alSourcei"); - if (lpOALFnTable->alSourcei == NULL) - { - warn("Failed to retrieve 'alSourcei' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcef = (LPALSOURCEF)dlsym(openal_library,"alSourcef"); - if (lpOALFnTable->alSourcef == NULL) - { - warn("Failed to retrieve 'alSourcef' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSource3f = (LPALSOURCE3F)dlsym(openal_library,"alSource3f"); - if (lpOALFnTable->alSource3f == NULL) - { - warn("Failed to retrieve 'alSource3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcefv = (LPALSOURCEFV)dlsym(openal_library,"alSourcefv"); - if (lpOALFnTable->alSourcefv == NULL) - { - warn("Failed to retrieve 'alSourcefv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcei = (LPALGETSOURCEI)dlsym(openal_library,"alGetSourcei"); - if (lpOALFnTable->alGetSourcei == NULL) - { - warn("Failed to retrieve 'alGetSourcei' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcef = (LPALGETSOURCEF)dlsym(openal_library,"alGetSourcef"); - if (lpOALFnTable->alGetSourcef == NULL) - { - warn("Failed to retrieve 'alGetSourcef' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcefv = (LPALGETSOURCEFV)dlsym(openal_library,"alGetSourcefv"); - if (lpOALFnTable->alGetSourcefv == NULL) - { - warn("Failed to retrieve 'alGetSourcefv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePlayv = (LPALSOURCEPLAYV)dlsym(openal_library,"alSourcePlayv"); - if (lpOALFnTable->alSourcePlayv == NULL) - { - warn("Failed to retrieve 'alSourcePlayv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceStopv = (LPALSOURCESTOPV)dlsym(openal_library,"alSourceStopv"); - if (lpOALFnTable->alSourceStopv == NULL) - { - warn("Failed to retrieve 'alSourceStopv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePlay = (LPALSOURCEPLAY)dlsym(openal_library,"alSourcePlay"); - if (lpOALFnTable->alSourcePlay == NULL) - { - warn("Failed to retrieve 'alSourcePlay' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePause = (LPALSOURCEPAUSE)dlsym(openal_library,"alSourcePause"); - if (lpOALFnTable->alSourcePause == NULL) - { - warn("Failed to retrieve 'alSourcePause' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceStop = (LPALSOURCESTOP)dlsym(openal_library,"alSourceStop"); - if (lpOALFnTable->alSourceStop == NULL) - { - warn("Failed to retrieve 'alSourceStop' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceRewind = (LPALSOURCEREWIND)dlsym(openal_library,"alSourceRewind"); - if (lpOALFnTable->alSourceRewind == NULL) - { - warn("Failed to retrieve 'alSourceRewind' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGenBuffers = (LPALGENBUFFERS)dlsym(openal_library,"alGenBuffers"); - if (lpOALFnTable->alGenBuffers == NULL) - { - warn("Failed to retrieve 'alGenBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteBuffers = (LPALDELETEBUFFERS)dlsym(openal_library,"alDeleteBuffers"); - if (lpOALFnTable->alDeleteBuffers == NULL) - { - warn("Failed to retrieve 'alDeleteBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsBuffer = (LPALISBUFFER)dlsym(openal_library,"alIsBuffer"); - if (lpOALFnTable->alIsBuffer == NULL) - { - warn("Failed to retrieve 'alIsBuffer' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alBufferData = (LPALBUFFERDATA)dlsym(openal_library,"alBufferData"); - if (lpOALFnTable->alBufferData == NULL) - { - warn("Failed to retrieve 'alBufferData' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBufferi = (LPALGETBUFFERI)dlsym(openal_library,"alGetBufferi"); - if (lpOALFnTable->alGetBufferi == NULL) - { - warn("Failed to retrieve 'alGetBufferi' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBufferf = (LPALGETBUFFERF)dlsym(openal_library,"alGetBufferf"); - if (lpOALFnTable->alGetBufferf == NULL) - { - warn("Failed to retrieve 'alGetBufferf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceQueueBuffers = (LPALSOURCEQUEUEBUFFERS)dlsym(openal_library,"alSourceQueueBuffers"); - if (lpOALFnTable->alSourceQueueBuffers == NULL) - { - warn("Failed to retrieve 'alSourceQueueBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceUnqueueBuffers = (LPALSOURCEUNQUEUEBUFFERS)dlsym(openal_library,"alSourceUnqueueBuffers"); - if (lpOALFnTable->alSourceUnqueueBuffers == NULL) - { - warn("Failed to retrieve 'alSourceUnqueueBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDistanceModel = (LPALDISTANCEMODEL)dlsym(openal_library,"alDistanceModel"); - if (lpOALFnTable->alDistanceModel == NULL) - { - warn("Failed to retrieve 'alDistanceModel' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDopplerFactor = (LPALDOPPLERFACTOR)dlsym(openal_library,"alDopplerFactor"); - if (lpOALFnTable->alDopplerFactor == NULL) - { - warn("Failed to retrieve 'alDopplerFactor' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDopplerVelocity = (LPALDOPPLERVELOCITY)dlsym(openal_library,"alDopplerVelocity"); - if (lpOALFnTable->alDopplerVelocity == NULL) - { - warn("Failed to retrieve 'alDopplerVelocity' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetString = (LPALCGETSTRING)dlsym(openal_library,"alcGetString"); - if (lpOALFnTable->alcGetString == NULL) - { - warn("Failed to retrieve 'alcGetString' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetIntegerv = (LPALCGETINTEGERV)dlsym(openal_library,"alcGetIntegerv"); - if (lpOALFnTable->alcGetIntegerv == NULL) - { - warn("Failed to retrieve 'alcGetIntegerv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcOpenDevice = (LPALCOPENDEVICE)dlsym(openal_library,"alcOpenDevice"); - if (lpOALFnTable->alcOpenDevice == NULL) - { - warn("Failed to retrieve 'alcOpenDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcCloseDevice = (LPALCCLOSEDEVICE)dlsym(openal_library,"alcCloseDevice"); - if (lpOALFnTable->alcCloseDevice == NULL) - { - warn("Failed to retrieve 'alcCloseDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcCreateContext = (LPALCCREATECONTEXT)dlsym(openal_library,"alcCreateContext"); - if (lpOALFnTable->alcCreateContext == NULL) - { - warn("Failed to retrieve 'alcCreateContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcMakeContextCurrent = (LPALCMAKECONTEXTCURRENT)dlsym(openal_library,"alcMakeContextCurrent"); - if (lpOALFnTable->alcMakeContextCurrent == NULL) - { - warn("Failed to retrieve 'alcMakeContextCurrent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcProcessContext = (LPALCPROCESSCONTEXT)dlsym(openal_library,"alcProcessContext"); - if (lpOALFnTable->alcProcessContext == NULL) - { - warn("Failed to retrieve 'alcProcessContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetCurrentContext = (LPALCGETCURRENTCONTEXT)dlsym(openal_library,"alcGetCurrentContext"); - if (lpOALFnTable->alcGetCurrentContext == NULL) - { - warn("Failed to retrieve 'alcGetCurrentContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetContextsDevice = (LPALCGETCONTEXTSDEVICE)dlsym(openal_library,"alcGetContextsDevice"); - if (lpOALFnTable->alcGetContextsDevice == NULL) - { - warn("Failed to retrieve 'alcGetContextsDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcSuspendContext = (LPALCSUSPENDCONTEXT)dlsym(openal_library,"alcSuspendContext"); - if (lpOALFnTable->alcSuspendContext == NULL) - { - warn("Failed to retrieve 'alcSuspendContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcDestroyContext = (LPALCDESTROYCONTEXT)dlsym(openal_library,"alcDestroyContext"); - if (lpOALFnTable->alcDestroyContext == NULL) - { - warn("Failed to retrieve 'alcDestroyContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetError = (LPALCGETERROR)dlsym(openal_library,"alcGetError"); - if (lpOALFnTable->alcGetError == NULL) - { - warn("Failed to retrieve 'alcGetError' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcIsExtensionPresent = (LPALCISEXTENSIONPRESENT)dlsym(openal_library,"alcIsExtensionPresent"); - if (lpOALFnTable->alcIsExtensionPresent == NULL) - { - warn("Failed to retrieve 'alcIsExtensionPresent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetProcAddress = (LPALCGETPROCADDRESS)dlsym(openal_library,"alcGetProcAddress"); - if (lpOALFnTable->alcGetProcAddress == NULL) - { - warn("Failed to retrieve 'alcGetProcAddress' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetEnumValue = (LPALCGETENUMVALUE)dlsym(openal_library,"alcGetEnumValue"); - if (lpOALFnTable->alcGetEnumValue == NULL) - { - warn("Failed to retrieve 'alcGetEnumValue' function address\n"); - return AL_FALSE; - } -#if defined(AL_ALEXT_PROTOTYPES) - //efx - lpOALFnTable->alGenEffects = (LPALGENEFFECTS)dlsym(openal_library, "alGenEffects"); - if (lpOALFnTable->alGenEffects == NULL) - { - warn("Failed to retrieve 'alGenEffects' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alEffecti = (LPALEFFECTI)dlsym(openal_library, "alEffecti"); - if (lpOALFnTable->alEffecti == NULL) - { - warn("Failed to retrieve 'alEffecti' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alEffectiv = (LPALEFFECTIV)dlsym(openal_library, "alEffectiv"); - if (lpOALFnTable->alEffectiv == NULL) - { - warn("Failed to retrieve 'alEffectiv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alEffectf = (LPALEFFECTF)dlsym(openal_library, "alEffectf"); - if (lpOALFnTable->alEffectf == NULL) - { - warn("Failed to retrieve 'alEffectf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alEffectfv = (LPALEFFECTFV)dlsym(openal_library, "alEffectfv"); - if (lpOALFnTable->alEffectfv == NULL) - { - warn("Failed to retrieve 'alEffectfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEffecti = (LPALGETEFFECTI)dlsym(openal_library, "alGetEffecti"); - if (lpOALFnTable->alGetEffecti == NULL) - { - warn("Failed to retrieve 'alGetEffecti' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEffectiv = (LPALGETEFFECTIV)dlsym(openal_library, "alGetEffectiv"); - if (lpOALFnTable->alGetEffectiv == NULL) - { - warn("Failed to retrieve 'alGetEffectiv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEffectf = (LPALGETEFFECTF)dlsym(openal_library, "alGetEffectf"); - if (lpOALFnTable->alGetEffectf == NULL) - { - warn("Failed to retrieve 'alGetEffectf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEffectfv = (LPALGETEFFECTFV)dlsym(openal_library, "alGetEffectfv"); - if (lpOALFnTable->alGetEffectfv == NULL) - { - warn("Failed to retrieve 'alGetEffectfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteEffects = (LPALDELETEEFFECTS)dlsym(openal_library, "alDeleteEffects"); - if (lpOALFnTable->alDeleteEffects == NULL) - { - warn("Failed to retrieve 'alDeleteEffects' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsEffect = (LPALISEFFECT)dlsym(openal_library, "alIsEffect"); - if (lpOALFnTable->alIsEffect == NULL) - { - warn("Failed to retrieve 'alIsEffect' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alAuxiliaryEffectSlotf = (LPALAUXILIARYEFFECTSLOTF)dlsym(openal_library, "alAuxiliaryEffectSlotf"); - if (lpOALFnTable->alAuxiliaryEffectSlotf == NULL) - { - warn("Failed to retrieve 'alAuxiliaryEffectSlotf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alAuxiliaryEffectSlotfv = (LPALAUXILIARYEFFECTSLOTFV)dlsym(openal_library, "alAuxiliaryEffectSlotfv"); - if (lpOALFnTable->alAuxiliaryEffectSlotfv == NULL) - { - warn("Failed to retrieve 'alAuxiliaryEffectSlotfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)dlsym(openal_library, "alAuxiliaryEffectSloti"); - if (lpOALFnTable->alAuxiliaryEffectSloti == NULL) - { - warn("Failed to retrieve 'alAuxiliaryEffectSloti' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alAuxiliaryEffectSlotiv = (LPALAUXILIARYEFFECTSLOTIV)dlsym(openal_library, "alAuxiliaryEffectSlotiv"); - if (lpOALFnTable->alAuxiliaryEffectSlotiv == NULL) - { - warn("Failed to retrieve 'alAuxiliaryEffectSlotiv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)dlsym(openal_library, "alIsAuxiliaryEffectSlot"); - if (lpOALFnTable->alIsAuxiliaryEffectSlot == NULL) - { - warn("Failed to retrieve 'alIsAuxiliaryEffectSlot' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)dlsym(openal_library, "alGenAuxiliaryEffectSlots"); - if (lpOALFnTable->alGenAuxiliaryEffectSlots == NULL) - { - warn("Failed to retrieve 'alGenAuxiliaryEffectSlots' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)dlsym(openal_library, "alDeleteAuxiliaryEffectSlots"); - if (lpOALFnTable->alDeleteAuxiliaryEffectSlots == NULL) - { - warn("Failed to retrieve 'alDeleteAuxiliaryEffectSlots' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetAuxiliaryEffectSlotf = (LPALGETAUXILIARYEFFECTSLOTF)dlsym(openal_library, "alGetAuxiliaryEffectSlotf"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotf == NULL) - { - warn("Failed to retrieve 'alGetAuxiliaryEffectSlotf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetAuxiliaryEffectSlotfv = (LPALGETAUXILIARYEFFECTSLOTFV)dlsym(openal_library, "alGetAuxiliaryEffectSlotfv"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotfv == NULL) - { - warn("Failed to retrieve 'alGetAuxiliaryEffectSlotfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetAuxiliaryEffectSloti = (LPALGETAUXILIARYEFFECTSLOTI)dlsym(openal_library, "alGetAuxiliaryEffectSloti"); - if (lpOALFnTable->alGetAuxiliaryEffectSloti == NULL) - { - warn("Failed to retrieve 'alGetAuxiliaryEffectSloti' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetAuxiliaryEffectSlotiv = (LPALGETAUXILIARYEFFECTSLOTIV)dlsym(openal_library, "alGetAuxiliaryEffectSlotiv"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotiv == NULL) - { - warn("Failed to retrieve 'alGetAuxiliaryEffectSlotiv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSource3i = (LPALSOURCE3I)dlsym(openal_library, "alSource3i"); - if (lpOALFnTable->alSource3i == NULL) - { - warn("Failed to retrieve 'alSource3i' function address\n"); - return AL_FALSE; - } -#endif - return AL_TRUE; -} - -ALvoid UnloadOAL10Library() -{ - if (openal_library != NULL) - dlclose(openal_library); -} diff --git a/Engine/source/sfx/openal/sfxALBuffer.cpp b/Engine/source/sfx/openal/sfxALBuffer.cpp index c276e2a3d..95481b314 100644 --- a/Engine/source/sfx/openal/sfxALBuffer.cpp +++ b/Engine/source/sfx/openal/sfxALBuffer.cpp @@ -30,8 +30,7 @@ //#define DEBUG_SPEW -SFXALBuffer* SFXALBuffer::create( const OPENALFNTABLE &oalft, - const ThreadSafeRef< SFXStream >& stream, +SFXALBuffer* SFXALBuffer::create( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description, bool useHardware ) { @@ -41,27 +40,24 @@ SFXALBuffer* SFXALBuffer::create( const OPENALFNTABLE &oalft, return NULL; } - SFXALBuffer *buffer = new SFXALBuffer( oalft, - stream, + SFXALBuffer *buffer = new SFXALBuffer( stream, description, useHardware ); return buffer; } -SFXALBuffer::SFXALBuffer( const OPENALFNTABLE &oalft, - const ThreadSafeRef< SFXStream >& stream, +SFXALBuffer::SFXALBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description, bool useHardware ) : Parent( stream, description ), mIs3d( description->mIs3D ), - mUseHardware( useHardware ), - mOpenAL( oalft ) + mUseHardware( useHardware ) { // Set up device buffers. if( !isStreaming() ) - mOpenAL.alGenBuffers( 1, &mALBuffer ); + alGenBuffers( 1, &mALBuffer ); } SFXALBuffer::~SFXALBuffer() @@ -70,13 +66,13 @@ SFXALBuffer::~SFXALBuffer() _getUniqueVoice()->stop(); // Release buffers. - if ( mOpenAL.alIsBuffer( mALBuffer )) - mOpenAL.alDeleteBuffers( 1, &mALBuffer ); + if ( alIsBuffer( mALBuffer )) + alDeleteBuffers( 1, &mALBuffer ); while( mFreeBuffers.size() ) { ALuint buffer = mFreeBuffers.last(); - mOpenAL.alDeleteBuffers( 1, &buffer ); + alDeleteBuffers( 1, &buffer ); mFreeBuffers.pop_back(); } } @@ -98,7 +94,7 @@ void SFXALBuffer::write( SFXInternal::SFXStreamPacket* const* packets, U32 num ) ALenum alFormat = _sfxFormatToALFormat( getFormat() ); AssertFatal( alFormat != 0, "SFXALBuffer::write() - format unsupported" ); - mOpenAL.alBufferData( mALBuffer, alFormat, + alBufferData( mALBuffer, alFormat, packet->data, packet->mSizeActual, getFormat().getSamplesPerSecond() ); destructSingle( packet ); @@ -112,19 +108,19 @@ void SFXALBuffer::write( SFXInternal::SFXStreamPacket* const* packets, U32 num ) ALuint source = _getUniqueVoice()->mSourceName; ALint numProcessed; - mOpenAL.alGetSourcei( source, AL_BUFFERS_PROCESSED, &numProcessed ); + alGetSourcei( source, AL_BUFFERS_PROCESSED, &numProcessed ); for( U32 i = 0; i < numProcessed; ++ i ) { // Unqueue the buffer. ALuint buffer; - mOpenAL.alSourceUnqueueBuffers( source, 1, &buffer ); + alSourceUnqueueBuffers( source, 1, &buffer ); // Update the sample offset on the voice. ALint size; - mOpenAL.alGetBufferi( buffer, AL_SIZE, &size ); + alGetBufferi( buffer, AL_SIZE, &size ); _getUniqueVoice()->mSampleOffset += size / getFormat().getBytesPerSample(); // Push the buffer onto the freelist. @@ -147,22 +143,22 @@ void SFXALBuffer::write( SFXInternal::SFXStreamPacket* const* packets, U32 num ) mFreeBuffers.pop_back(); } else - mOpenAL.alGenBuffers( 1, &buffer ); + alGenBuffers( 1, &buffer ); // Upload the data. ALenum alFormat = _sfxFormatToALFormat( getFormat() ); AssertFatal( alFormat != 0, "SFXALBuffer::write() - format unsupported" ); - AssertFatal( mOpenAL.alIsBuffer( buffer ), "SFXALBuffer::write() - buffer invalid" ); + AssertFatal( alIsBuffer( buffer ), "SFXALBuffer::write() - buffer invalid" ); - mOpenAL.alBufferData( buffer, alFormat, + alBufferData( buffer, alFormat, packet->data, packet->mSizeActual, getFormat().getSamplesPerSecond() ); destructSingle( packet ); // Queue the buffer. - mOpenAL.alSourceQueueBuffers( source, 1, &buffer ); + alSourceQueueBuffers( source, 1, &buffer ); } } @@ -183,12 +179,12 @@ void SFXALBuffer::_flush() ALuint source = _getUniqueVoice()->mSourceName; ALint numQueued; - mOpenAL.alGetSourcei( source, AL_BUFFERS_QUEUED, &numQueued ); + alGetSourcei( source, AL_BUFFERS_QUEUED, &numQueued ); for( U32 i = 0; i < numQueued; ++ i ) { ALuint buffer; - mOpenAL.alSourceUnqueueBuffers( source, 1, &buffer ); + alSourceUnqueueBuffers( source, 1, &buffer ); mFreeBuffers.push_back( buffer ); } @@ -203,20 +199,20 @@ void SFXALBuffer::_flush() // issues any concurrent state changes on the voice resulting in us losing state here. ALuint newSource; - mOpenAL.alGenSources( 1, &newSource ); + alGenSources( 1, &newSource ); #define COPY_F( name ) \ { \ F32 val; \ - mOpenAL.alGetSourcef( source, name, &val ); \ - mOpenAL.alSourcef( source, name, val ); \ + alGetSourcef( source, name, &val ); \ + alSourcef( source, name, val ); \ } #define COPY_FV( name ) \ { \ VectorF val; \ - mOpenAL.alGetSourcefv( source, name, val ); \ - mOpenAL.alSourcefv( source, name, val ); \ + alGetSourcefv( source, name, val ); \ + alSourcefv( source, name, val ); \ } COPY_F( AL_REFERENCE_DISTANCE ); @@ -232,7 +228,7 @@ void SFXALBuffer::_flush() COPY_FV( AL_DIRECTION ); _getUniqueVoice()->mSourceName = newSource; - mOpenAL.alDeleteSources( 1, &source ); + alDeleteSources( 1, &source ); #endif } diff --git a/Engine/source/sfx/openal/sfxALBuffer.h b/Engine/source/sfx/openal/sfxALBuffer.h index 26864a3d0..609add4f1 100644 --- a/Engine/source/sfx/openal/sfxALBuffer.h +++ b/Engine/source/sfx/openal/sfxALBuffer.h @@ -24,13 +24,13 @@ #define _SFXALBUFFER_H_ #ifndef _LOADOAL_H - #include "sfx/openal/LoadOAL.h" +#include "sfx/openal/LoadOAL.h" #endif #ifndef _SFXINTERNAL_H_ - #include "sfx/sfxInternal.h" +#include "sfx/sfxInternal.h" #endif #ifndef _TVECTOR_H_ - #include "core/util/tVector.h" +#include "core/util/tVector.h" #endif @@ -39,81 +39,95 @@ class SFXALVoice; class SFXALBuffer : public SFXBuffer { - public: +public: - typedef SFXBuffer Parent; + typedef SFXBuffer Parent; - friend class SFXALDevice; - friend class SFXALVoice; + friend class SFXALDevice; + friend class SFXALVoice; - protected: - - /// AL buffer in case this is a static, non-streaming buffer. - ALuint mALBuffer; - - /// Free buffers for use in queuing in case this is a streaming buffer. - Vector< ALuint > mFreeBuffers; +protected: - /// - SFXALBuffer( const OPENALFNTABLE &oalft, - const ThreadSafeRef< SFXStream >& stream, - SFXDescription* description, - bool useHardware ); + /// AL buffer in case this is a static, non-streaming buffer. + ALuint mALBuffer; - /// - bool mIs3d; + /// Free buffers for use in queuing in case this is a streaming buffer. + Vector< ALuint > mFreeBuffers; - /// - bool mUseHardware; + /// + SFXALBuffer(const ThreadSafeRef< SFXStream >& stream, + SFXDescription* description, + bool useHardware); - const OPENALFNTABLE &mOpenAL; + /// + bool mIs3d; - /// - ALenum _getALFormat() const + /// + bool mUseHardware; + /// + ALenum _getALFormat() const + { + return _sfxFormatToALFormat(getFormat()); + } + + /// + static ALenum _sfxFormatToALFormat(const SFXFormat& format) + { + const U32 channels = format.getChannels(); + const SFXSampleType type = format.getSampleType(); + + switch (type) { - return _sfxFormatToALFormat( getFormat() ); + case Sample_Int8: + if (channels == 1) return AL_FORMAT_MONO8; + if (channels == 2) return AL_FORMAT_STEREO8; + break; + + case Sample_Int16: + if (channels == 1) return AL_FORMAT_MONO16; + if (channels == 2) return AL_FORMAT_STEREO16; + break; + + case Sample_Float: + if (channels == 1) return AL_FORMAT_MONO_FLOAT32; + if (channels == 2) return AL_FORMAT_STEREO_FLOAT32; + break; + + case Sample_IMA4: + if (channels == 1) return AL_FORMAT_MONO_IMA4; + if (channels == 2) return AL_FORMAT_STEREO_IMA4; + break; + + case Sample_MSADPCM: + // Requires OpenAL Soft MSADPCM extension + if (channels == 1) return AL_FORMAT_MONO_MSADPCM_SOFT; + if (channels == 2) return AL_FORMAT_STEREO_MSADPCM_SOFT; + break; } - /// - static ALenum _sfxFormatToALFormat( const SFXFormat& format ) - { - if( format.getChannels() == 2 ) - { - const U32 bps = format.getBitsPerSample(); - if( bps == 16 ) - return AL_FORMAT_STEREO8; - else if( bps == 32 ) - return AL_FORMAT_STEREO16; - } - else if( format.getChannels() == 1 ) - { - const U32 bps = format.getBitsPerSample(); - if( bps == 8 ) - return AL_FORMAT_MONO8; - else if( bps == 16 ) - return AL_FORMAT_MONO16; - } - return 0; - } + // Unsupported channel count or layout + Con::errorf("_sfxFormatToALFormat - Unsupported format: channels=%d, type=%d", + channels, type); + return 0; + } - /// - SFXALVoice* _getUniqueVoice() const - { - return ( SFXALVoice* ) mUniqueVoice.getPointer(); - } + /// + SFXALVoice* _getUniqueVoice() const + { + return (SFXALVoice*)mUniqueVoice.getPointer(); + } - // SFXBuffer. - void write( SFXInternal::SFXStreamPacket* const* packets, U32 num ) override; - void _flush() override; + // SFXBuffer. + void write(SFXInternal::SFXStreamPacket* const* packets, U32 num) override; + void _flush() override; - public: +public: - static SFXALBuffer* create( const OPENALFNTABLE &oalft, - const ThreadSafeRef< SFXStream >& stream, - SFXDescription* description, - bool useHardware ); + static SFXALBuffer* create(const ThreadSafeRef< SFXStream >& stream, + SFXDescription* description, + bool useHardware); - virtual ~SFXALBuffer(); + virtual ~SFXALBuffer(); }; -#endif // _SFXALBUFFER_H_ \ No newline at end of file +#endif // _SFXALBUFFER_H_ diff --git a/Engine/source/sfx/openal/sfxALDevice.cpp b/Engine/source/sfx/openal/sfxALDevice.cpp index 765cb01ff..306b98659 100644 --- a/Engine/source/sfx/openal/sfxALDevice.cpp +++ b/Engine/source/sfx/openal/sfxALDevice.cpp @@ -24,6 +24,90 @@ #include "sfx/openal/sfxALBuffer.h" #include "platform/async/asyncUpdate.h" +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/efx.h" +#include "AL/alext.h" + +#ifndef ALC_CONNECTED +#define ALC_CONNECTED 0x313 +#endif + +#ifndef ALC_DEVICE_CLOCK_SOFT +#define ALC_DEVICE_CLOCK_SOFT 0x1600 +#endif + +#ifndef ALC_DEVICE_LATENCY_SOFT +#define ALC_DEVICE_LATENCY_SOFT 0x1601 +#endif + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#define FUNCTION_CAST(T, ptr) (union{void *p; T f;}){ptr}.f +#elif defined(__cplusplus) +#define FUNCTION_CAST(T, ptr) reinterpret_cast(ptr) +#else +#define FUNCTION_CAST(T, ptr) (T)(ptr) +#endif + +/* Effect object functions */ +static LPALGENFILTERS alGenFilters{ nullptr }; +static LPALDELETEFILTERS alDeleteFilters{ nullptr }; +static LPALISFILTER alIsFilter{ nullptr }; +static LPALFILTERF alFilterf{ nullptr }; +static LPALFILTERFV alFilterfv{ nullptr }; +static LPALFILTERI alFilteri{ nullptr }; +static LPALFILTERIV alFilteriv{ nullptr }; +static LPALGETFILTERF alGetFilterf{ nullptr }; +static LPALGETFILTERFV alGetFilterfv{ nullptr }; +static LPALGETFILTERI alGetFilteri{ nullptr }; +static LPALGETFILTERIV alGetFilteriv{ nullptr }; +static LPALGENEFFECTS alGenEffects{ nullptr }; +static LPALDELETEEFFECTS alDeleteEffects{ nullptr }; +static LPALISEFFECT alIsEffect{ nullptr }; +static LPALEFFECTF alEffectf{ nullptr }; +static LPALEFFECTFV alEffectfv{ nullptr }; +static LPALEFFECTI alEffecti{ nullptr }; +static LPALEFFECTIV alEffectiv{ nullptr }; +static LPALGETEFFECTF alGetEffectf{ nullptr }; +static LPALGETEFFECTFV alGetEffectfv{ nullptr }; +static LPALGETEFFECTI alGetEffecti{ nullptr }; +static LPALGETEFFECTIV alGetEffectiv{ nullptr }; +static LPALGENAUXILIARYEFFECTSLOTS alGenAuxiliaryEffectSlots{ nullptr }; +static LPALDELETEAUXILIARYEFFECTSLOTS alDeleteAuxiliaryEffectSlots{ nullptr }; +static LPALISAUXILIARYEFFECTSLOT alIsAuxiliaryEffectSlot{ nullptr }; +static LPALAUXILIARYEFFECTSLOTF alAuxiliaryEffectSlotf{ nullptr }; +static LPALAUXILIARYEFFECTSLOTFV alAuxiliaryEffectSlotfv{ nullptr }; +static LPALAUXILIARYEFFECTSLOTI alAuxiliaryEffectSloti{ nullptr }; +static LPALAUXILIARYEFFECTSLOTIV alAuxiliaryEffectSlotiv{ nullptr }; +static LPALGETAUXILIARYEFFECTSLOTF alGetAuxiliaryEffectSlotf{ nullptr }; +static LPALGETAUXILIARYEFFECTSLOTFV alGetAuxiliaryEffectSlotfv{ nullptr }; +static LPALGETAUXILIARYEFFECTSLOTI alGetAuxiliaryEffectSloti{ nullptr }; +static LPALGETAUXILIARYEFFECTSLOTIV alGetAuxiliaryEffectSlotiv{ nullptr }; +static LPALCGETSTRINGISOFT alcGetStringiSOFT{ nullptr }; +static LPALCRESETDEVICESOFT alcResetDeviceSOFT{ nullptr }; +static LPALCREOPENDEVICESOFT alcReopenDeviceSOFT{ nullptr }; +static LPALCGETINTEGER64VSOFT alcGetInteger64vSOFT{ nullptr }; + +class SFXALRegisterProvider +{ +public: + SFXALRegisterProvider() + { + SFXSystem::getRegisterProviderSignal().notify(&SFXALDevice::enumerateProviders); + } +}; + +static SFXALRegisterProvider pSFXALRegisterProvider; + +SFXProvider::CreateProviderInstanceDelegate SFXALDevice::mCreateDeviceInstance(SFXALDevice::createInstance); + +SFXDevice* SFXALDevice::createInstance(U32 providerIndex) +{ + SFXALDevice* dev = new SFXALDevice(providerIndex); + return dev; +} + + //---------------------------------------------------------------------------- // STATIC OPENAL FUNCTIONS //---------------------------------------------------------------------------- @@ -35,39 +119,54 @@ void SFXALDevice::printALInfo(ALCdevice* device) const ALCchar* devname = NULL; Con::printBlankLine(); - if (mOpenAL.alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE) + if (alcIsExtensionPresent(device, "ALC_ENUMERATE_ALL_EXT") != AL_FALSE) { - devname = mOpenAL.alcGetString(device, ALC_ALL_DEVICES_SPECIFIER); + devname = alcGetString(device, ALC_ALL_DEVICES_SPECIFIER); } else { - devname = mOpenAL.alcGetString(device, ALC_DEVICE_SPECIFIER); + devname = alcGetString(device, ALC_DEVICE_SPECIFIER); } Con::printf("| Device info for: %s ", devname); } - mOpenAL.alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major); - mOpenAL.alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor); + alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major); + alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor); Con::printf("| OpenAL Version: %d.%d", major, minor); if (device) { - Con::printf("%s", mOpenAL.alcGetString(device, ALC_EXTENSIONS)); + const ALchar* extStr = alcGetString(device, ALC_EXTENSIONS); + if (extStr) + { + Con::printf("| SFXALDevice - Supported ALC extensions:"); - U32 err = mOpenAL.alcGetError(device); + // Copy to a modifiable string. + char* extCopy = dStrdup(extStr); + char* token = dStrtok(extCopy, " "); + while (token) + { + Con::printf("| %s", token); + token = dStrtok(NULL, " "); + } + + dFree(extCopy); + } + + U32 err = alcGetError(device); if (err != ALC_NO_ERROR) - Con::errorf("SFXALDevice - Error Retrieving ALC Extensions: %s", mOpenAL.alcGetString(device, err)); + Con::errorf("SFXALDevice - Error Retrieving ALC Extensions: %s", alcGetString(device, err)); } } S32 SFXALDevice::getMaxSources() { - mOpenAL.alGetError(); + alGetError(); ALCint nummono; - mOpenAL.alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &nummono); + alcGetIntegerv(mDevice, ALC_MONO_SOURCES, 1, &nummono); if(nummono == 0) nummono = getMaxSourcesOld(); @@ -81,21 +180,21 @@ S32 SFXALDevice::getMaxSourcesOld() S32 sourceCount = 0; // clear errors. - mOpenAL.alGetError(); + alGetError(); for(sourceCount = 0; sourceCount < 256; sourceCount++) { - mOpenAL.alGenSources(1,&uiSource[sourceCount]); - if(mOpenAL.alGetError() != AL_NO_ERROR) + alGenSources(1,&uiSource[sourceCount]); + if(alGetError() != AL_NO_ERROR) break; } - mOpenAL.alDeleteSources(sourceCount, uiSource); - if(mOpenAL.alGetError() != AL_NO_ERROR) + alDeleteSources(sourceCount, uiSource); + if(alGetError() != AL_NO_ERROR) { for(U32 i = 0; i < 256; i++) { - mOpenAL.alDeleteSources(1,&uiSource[i]); + alDeleteSources(1,&uiSource[i]); } } @@ -103,55 +202,31 @@ S32 SFXALDevice::getMaxSourcesOld() } -//----------------------------------------------------------------------------- - -SFXALDevice::SFXALDevice( SFXProvider *provider, - const OPENALFNTABLE &openal, - String name, - bool useHardware, - S32 maxBuffers ) - : Parent( name, provider, useHardware, maxBuffers ), - mOpenAL( openal ), - mContext( NULL ), - mDevice( NULL ), +SFXALDevice::SFXALDevice(U32 providerIndex) + : mContext(NULL), + mDevice(NULL), mDistanceModel(SFXDistanceModelLinear), mDistanceFactor(1.0f), - mRolloffFactor( 1.0f ), + mRolloffFactor(1.0f), mUserRolloffFactor(1.0f) { - mMaxBuffers = getMax( maxBuffers, 8 ); + SFXProvider* p = SFXSystem::getProvider(providerIndex); - // TODO: The OpenAL device doesn't set the primary buffer - // $pref::SFX::frequency or $pref::SFX::bitrate! - //check auxiliary device sends 4 and add them to the device - ALint attribs[4] = { 0 }; -#if defined(AL_ALEXT_PROTOTYPES) - ALCint iSends = 0; - attribs[0] = ALC_MAX_AUXILIARY_SENDS; -#endif - attribs[1] = 4; + mDevice = alcOpenDevice(p->getName()); - printALInfo(NULL); - - mDevice = mOpenAL.alcOpenDevice( name ); - U32 err = mOpenAL.alcGetError(mDevice); + U32 err = alcGetError(mDevice); if (err != ALC_NO_ERROR) - Con::errorf("SFXALDevice - Device Initialization Error: %s", mOpenAL.alcGetString(mDevice, err)); + Con::errorf("SFXALDevice - Device Initialization Error: %s", alcGetString(mDevice, err)); - if( mDevice ) + if (mDevice) { - mContext = mOpenAL.alcCreateContext( mDevice, attribs ); + mContext = alcCreateContext(mDevice, NULL); - if( mContext ) - mOpenAL.alcMakeContextCurrent( mContext ); + if (mContext) + alcMakeContextCurrent(mContext); -#if defined(AL_ALEXT_PROTOTYPES) - mOpenAL.alcGetIntegerv(mDevice, ALC_MAX_AUXILIARY_SENDS, 1, &iSends); -#endif - err = mOpenAL.alcGetError( mDevice ); - if( err != ALC_NO_ERROR ) - Con::errorf( "SFXALDevice - Context Initialization Error: %s", mOpenAL.alcGetString( mDevice, err ) ); + Con::errorf( "SFXALDevice - Context Initialization Error: %s", alcGetString( mDevice, err ) ); } AssertFatal( mDevice != NULL && mContext != NULL, "Failed to create OpenAL device and/or context!" ); @@ -168,20 +243,64 @@ SFXALDevice::SFXALDevice( SFXProvider *provider, } #endif -#if defined(AL_ALEXT_PROTOTYPES) - dMemset(effectSlot, 0, sizeof(effectSlot)); - dMemset(effect, 0, sizeof(effect)); - uLoop = 0; -#endif + // --- Capabilities --- + if (alcIsExtensionPresent(mDevice, "ALC_EXT_EFX") == AL_TRUE) + mCaps |= CAPS_Reverb | CAPS_Occlusion; + if (alcIsExtensionPresent(mDevice, "ALC_SOFT_HRTF") == AL_TRUE) + mCaps |= CAPS_HRTF; + if (alIsExtensionPresent("AL_EXT_float32") == AL_TRUE) + mCaps |= CAPS_Float32; + if (alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE) + mCaps |= CAPS_MonoStereo; + + if (mCaps & CAPS_Reverb) + { +#define LOAD_PROC(T, x) ((x) = FUNCTION_CAST(T, alGetProcAddress(#x))) + LOAD_PROC(LPALGENEFFECTS, alGenEffects); + LOAD_PROC(LPALDELETEEFFECTS, alDeleteEffects); + LOAD_PROC(LPALISEFFECT, alIsEffect); + LOAD_PROC(LPALEFFECTI, alEffecti); + LOAD_PROC(LPALEFFECTIV, alEffectiv); + LOAD_PROC(LPALEFFECTF, alEffectf); + LOAD_PROC(LPALEFFECTFV, alEffectfv); + LOAD_PROC(LPALGETEFFECTI, alGetEffecti); + LOAD_PROC(LPALGETEFFECTIV, alGetEffectiv); + LOAD_PROC(LPALGETEFFECTF, alGetEffectf); + LOAD_PROC(LPALGETEFFECTFV, alGetEffectfv); + + LOAD_PROC(LPALGENAUXILIARYEFFECTSLOTS, alGenAuxiliaryEffectSlots); + LOAD_PROC(LPALDELETEAUXILIARYEFFECTSLOTS, alDeleteAuxiliaryEffectSlots); + LOAD_PROC(LPALISAUXILIARYEFFECTSLOT, alIsAuxiliaryEffectSlot); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTI, alAuxiliaryEffectSloti); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTIV, alAuxiliaryEffectSlotiv); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTF, alAuxiliaryEffectSlotf); + LOAD_PROC(LPALAUXILIARYEFFECTSLOTFV, alAuxiliaryEffectSlotfv); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTI, alGetAuxiliaryEffectSloti); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTIV, alGetAuxiliaryEffectSlotiv); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTF, alGetAuxiliaryEffectSlotf); + LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv); +#undef LOAD_PROC + + // generate our auxiliary slot for the effects. + // alGenAuxiliaryEffectSlots(1, &mAuxSlot); + } + + // --- Device frequency --- + ALCint freq = 0; + alcGetIntegerv(mDevice, ALC_FREQUENCY, 1, &freq); + if (freq > 0) + Con::setIntVariable("$pref::SFX::frequency", freq); + else + Con::setIntVariable("$pref::SFX::frequency", 44100); // default + + // --- Bitrate approximation --- + U32 bitrate = (mCaps & CAPS_Float32) ? 32 : 16; + Con::setIntVariable("$pref::SFX::bitrate", bitrate); printALInfo(mDevice); - mMaxBuffers = getMaxSources(); - - // this should be max sources. - Con::printf("| Max Sources: %d", mMaxBuffers); - + Con::setIntVariable("$pref::SFX::maxSoftwareBuffers", mMaxBuffers); } //----------------------------------------------------------------------------- @@ -189,26 +308,60 @@ SFXALDevice::SFXALDevice( SFXProvider *provider, SFXALDevice::~SFXALDevice() { _releaseAllResources(); - ///cleanup our effects -#if defined(AL_ALEXT_PROTOTYPES) - mOpenAL.alDeleteAuxiliaryEffectSlots(4, effectSlot); - mOpenAL.alDeleteEffects(2, effect); -#endif + ///cleanup of effects ends - mOpenAL.alcMakeContextCurrent( NULL ); - mOpenAL.alcDestroyContext( mContext ); - mOpenAL.alcCloseDevice( mDevice ); + alcMakeContextCurrent( NULL ); + alcDestroyContext( mContext ); + alcCloseDevice( mDevice ); } //----------------------------------------------------------------------------- +void SFXALDevice::enumerateProviders(Vector& providerList) +{ + const ALCchar* devices; + U32 index = providerList.size(); + const ALCchar* defaultDeviceName; + + if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE) + { + devices = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER); + defaultDeviceName = alcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER); + } + else + { + devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER); + defaultDeviceName = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER); + } + + const ALCchar* currentDevice = devices; + + while (*currentDevice != '\0') + { + SFXProvider* toAdd = new SFXProvider; + toAdd->mName = String::ToString(currentDevice); + toAdd->mIndex = index; + toAdd->mDeviceType = Output; + toAdd->mType = OpenAL; + toAdd->mCreateDeviceInstanceDelegate = mCreateDeviceInstance; + + if (String::compare(currentDevice, defaultDeviceName) == 0) + toAdd->mDefault = true; + + currentDevice += dStrlen(currentDevice) + 1; + index++; + + providerList.push_back(toAdd); + } + +} + SFXBuffer* SFXALDevice::createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ) { AssertFatal( stream, "SFXALDevice::createBuffer() - Got null stream!" ); AssertFatal( description, "SFXALDevice::createBuffer() - Got null description!" ); - SFXALBuffer* buffer = SFXALBuffer::create( mOpenAL, - stream, + SFXALBuffer* buffer = SFXALBuffer::create( stream, description, mUseHardware ); if ( !buffer ) @@ -258,14 +411,9 @@ void SFXALDevice::setListener( U32 index, const SFXListenerProperties& listener const VectorF &velocity = listener.getVelocity(); - mOpenAL.alListenerfv( AL_POSITION, pos ); - mOpenAL.alListenerfv( AL_VELOCITY, velocity ); - mOpenAL.alListenerfv( AL_ORIENTATION, (const F32 *)&tupple[0] ); - ///Pass a unit size to openal, 1.0 assumes 1 meter to 1 game unit. - ///Crucial for air absorbtion calculations. -#if defined(AL_ALEXT_PROTOTYPES) - mOpenAL.alListenerf(AL_METERS_PER_UNIT, 1.0f); -#endif + alListenerfv( AL_POSITION, pos ); + alListenerfv( AL_VELOCITY, velocity ); + alListenerfv( AL_ORIENTATION, (const F32 *)&tupple[0] ); } //----------------------------------------------------------------------------- @@ -275,19 +423,19 @@ void SFXALDevice::setDistanceModel( SFXDistanceModel model ) switch( model ) { case SFXDistanceModelLinear: - mOpenAL.alDistanceModel( AL_LINEAR_DISTANCE_CLAMPED ); + alDistanceModel( AL_LINEAR_DISTANCE_CLAMPED ); if( mRolloffFactor != 1.0f ) _setRolloffFactor( 1.0f ); // No rolloff on linear. break; case SFXDistanceModelLogarithmic: - mOpenAL.alDistanceModel( AL_INVERSE_DISTANCE_CLAMPED ); + alDistanceModel( AL_INVERSE_DISTANCE_CLAMPED ); if( mUserRolloffFactor != mRolloffFactor ) _setRolloffFactor( mUserRolloffFactor ); break; /// create a case for our exponential distance model case SFXDistanceModelExponent: - mOpenAL.alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED); + alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED); if (mUserRolloffFactor != mRolloffFactor) _setRolloffFactor(mUserRolloffFactor); break; @@ -303,7 +451,7 @@ void SFXALDevice::setDistanceModel( SFXDistanceModel model ) void SFXALDevice::setDopplerFactor( F32 factor ) { - mOpenAL.alDopplerFactor( factor ); + alDopplerFactor( factor ); } //----------------------------------------------------------------------------- @@ -313,7 +461,7 @@ void SFXALDevice::_setRolloffFactor( F32 factor ) mRolloffFactor = factor; for( U32 i = 0, num = mVoices.size(); i < num; ++ i ) - mOpenAL.alSourcef( ( ( SFXALVoice* ) mVoices[ i ] )->mSourceName, AL_ROLLOFF_FACTOR, factor ); + alSourcef( ( ( SFXALVoice* ) mVoices[ i ] )->mSourceName, AL_ROLLOFF_FACTOR, factor ); } //----------------------------------------------------------------------------- @@ -328,110 +476,7 @@ void SFXALDevice::setRolloffFactor( F32 factor ) mUserRolloffFactor = factor; } -#if defined(AL_ALEXT_PROTOTYPES) -void SFXALDevice::openSlots() +void SFXALDevice::setSpeedOfSound(F32 speedOfSound) { - for (uLoop = 0; uLoop < 4; uLoop++) - { - mOpenAL.alGenAuxiliaryEffectSlots(1, &effectSlot[uLoop]); - } - - for (uLoop = 0; uLoop < 2; uLoop++) - { - mOpenAL.alGenEffects(1, &effect[uLoop]); - } - ///debug string output so we know our slots are open - Platform::outputDebugString("Slots Open"); + alSpeedOfSound(speedOfSound); } - -///create reverb effect -void SFXALDevice::setReverb(const SFXReverbProperties& reverb) -{ - ///output a debug string so we know each time the reverb changes - Platform::outputDebugString("Updated"); - - ///load an efxeaxreverb default and add our values from - ///sfxreverbproperties to it - EFXEAXREVERBPROPERTIES prop = EFX_REVERB_PRESET_GENERIC; - - prop.flDensity = reverb.flDensity; - prop.flDiffusion = reverb.flDiffusion; - prop.flGain = reverb.flGain; - prop.flGainHF = reverb.flGainHF; - prop.flGainLF = reverb.flGainLF; - prop.flDecayTime = reverb.flDecayTime; - prop.flDecayHFRatio = reverb.flDecayHFRatio; - prop.flDecayLFRatio = reverb.flDecayLFRatio; - prop.flReflectionsGain = reverb.flReflectionsGain; - prop.flReflectionsDelay = reverb.flReflectionsDelay; - prop.flLateReverbGain = reverb.flLateReverbGain; - prop.flLateReverbDelay = reverb.flLateReverbDelay; - prop.flEchoTime = reverb.flEchoTime; - prop.flEchoDepth = reverb.flEchoDepth; - prop.flModulationTime = reverb.flModulationTime; - prop.flModulationDepth = reverb.flModulationDepth; - prop.flAirAbsorptionGainHF = reverb.flAirAbsorptionGainHF; - prop.flHFReference = reverb.flHFReference; - prop.flLFReference = reverb.flLFReference; - prop.flRoomRolloffFactor = reverb.flRoomRolloffFactor; - prop.iDecayHFLimit = reverb.iDecayHFLimit; - - if (mOpenAL.alGetEnumValue("AL_EFFECT_EAXREVERB") != 0) - { - - /// EAX Reverb is available. Set the EAX effect type - - mOpenAL.alEffecti(effect[0], AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB); - - ///add our values to the setup of the reverb - - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DENSITY, prop.flDensity); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DIFFUSION, prop.flDiffusion); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAIN, prop.flGain); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAINHF, prop.flGainHF); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_GAINLF, prop.flGainLF); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_TIME, prop.flDecayTime); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_HFRATIO, prop.flDecayHFRatio); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_DECAY_LFRATIO, prop.flDecayLFRatio); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_REFLECTIONS_GAIN, prop.flReflectionsGain); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_REFLECTIONS_DELAY, prop.flReflectionsDelay); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LATE_REVERB_GAIN, prop.flLateReverbGain); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LATE_REVERB_DELAY, prop.flLateReverbDelay); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ECHO_TIME, prop.flEchoTime); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ECHO_DEPTH, prop.flEchoDepth); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_MODULATION_TIME, prop.flModulationTime); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_MODULATION_DEPTH, prop.flModulationDepth); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_AIR_ABSORPTION_GAINHF, prop.flAirAbsorptionGainHF); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_HFREFERENCE, prop.flHFReference); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_LFREFERENCE, prop.flLFReference); - mOpenAL.alEffectf(effect[0], AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, prop.flRoomRolloffFactor); - mOpenAL.alEffecti(effect[0], AL_EAXREVERB_DECAY_HFLIMIT, prop.iDecayHFLimit); - mOpenAL.alAuxiliaryEffectSloti(1, AL_EFFECTSLOT_EFFECT, effect[0]); - Platform::outputDebugString("eax reverb properties set"); - - } - else - { - - /// No EAX Reverb. Set the standard reverb effect - mOpenAL.alEffecti(effect[0], AL_EFFECT_TYPE, AL_EFFECT_REVERB); - - mOpenAL.alEffectf(effect[0], AL_REVERB_DENSITY, prop.flDensity); - mOpenAL.alEffectf(effect[0], AL_REVERB_DIFFUSION, prop.flDiffusion); - mOpenAL.alEffectf(effect[0], AL_REVERB_GAIN, prop.flGain); - mOpenAL.alEffectf(effect[0], AL_REVERB_GAINHF, prop.flGainHF); - mOpenAL.alEffectf(effect[0], AL_REVERB_DECAY_TIME, prop.flDecayTime); - mOpenAL.alEffectf(effect[0], AL_REVERB_DECAY_HFRATIO, prop.flDecayHFRatio); - mOpenAL.alEffectf(effect[0], AL_REVERB_REFLECTIONS_GAIN, prop.flReflectionsGain); - mOpenAL.alEffectf(effect[0], AL_REVERB_REFLECTIONS_DELAY, prop.flReflectionsDelay); - mOpenAL.alEffectf(effect[0], AL_REVERB_LATE_REVERB_GAIN, prop.flLateReverbGain); - mOpenAL.alEffectf(effect[0], AL_REVERB_LATE_REVERB_DELAY, prop.flLateReverbDelay); - mOpenAL.alEffectf(effect[0], AL_REVERB_AIR_ABSORPTION_GAINHF, prop.flAirAbsorptionGainHF); - mOpenAL.alEffectf(effect[0], AL_REVERB_ROOM_ROLLOFF_FACTOR, prop.flRoomRolloffFactor); - mOpenAL.alEffecti(effect[0], AL_REVERB_DECAY_HFLIMIT, prop.iDecayHFLimit); - mOpenAL.alAuxiliaryEffectSloti(1, AL_EFFECTSLOT_EFFECT, effect[0]); - - } - -} -#endif diff --git a/Engine/source/sfx/openal/sfxALDevice.h b/Engine/source/sfx/openal/sfxALDevice.h index 3d2bf5e78..92af85f4b 100644 --- a/Engine/source/sfx/openal/sfxALDevice.h +++ b/Engine/source/sfx/openal/sfxALDevice.h @@ -23,8 +23,6 @@ #ifndef _SFXALDEVICE_H_ #define _SFXALDEVICE_H_ -class SFXProvider; - #ifndef _SFXDEVICE_H_ # include "sfx/sfxDevice.h" #endif @@ -45,6 +43,9 @@ class SFXProvider; # include "sfx/openal/LoadOAL.h" #endif +#ifndef _SFXSYSTEM_H_ +#include "sfx/sfxSystem.h" +#endif class SFXALDevice : public SFXDevice { @@ -53,6 +54,8 @@ class SFXALDevice : public SFXDevice typedef SFXDevice Parent; friend class SFXALVoice; // mDistanceFactor, mRolloffFactor + static SFXDevice* createInstance(U32 adapterIndex); + void printALInfo(ALCdevice* device); void printHRTFInfo(ALCdevice* device); void getEFXInfo(ALCdevice* device); @@ -61,16 +64,12 @@ class SFXALDevice : public SFXDevice // Compatibility with pre openal 1.2 S32 getMaxSourcesOld(); - SFXALDevice( SFXProvider *provider, - const OPENALFNTABLE &openal, - String name, - bool useHardware, - S32 maxBuffers ); + SFXALDevice(U32 providerIndex); virtual ~SFXALDevice(); protected: - + static SFXProvider::CreateProviderInstanceDelegate mCreateDeviceInstance; OPENALFNTABLE mOpenAL; ALCcontext *mContext; @@ -85,7 +84,7 @@ class SFXALDevice : public SFXDevice void _setRolloffFactor( F32 factor ); public: - + static void enumerateProviders(Vector& providerList); // SFXDevice. SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ) override; SFXVoice* createVoice( bool is3D, SFXBuffer *buffer ) override; @@ -93,17 +92,8 @@ class SFXALDevice : public SFXDevice void setDistanceModel( SFXDistanceModel model ) override; void setDopplerFactor( F32 factor ) override; void setRolloffFactor( F32 factor ) override; -#if defined(AL_ALEXT_PROTOTYPES) - //function for openAL to open slots - virtual void openSlots(); - //slots - ALuint effectSlot[4] = { 0 }; - ALuint effect[2] = { 0 }; - ALuint uLoop; - //get values from sfxreverbproperties and pass it to openal device - virtual void setReverb(const SFXReverbProperties& reverb); -#endif void resetReverb() override {} + void setSpeedOfSound(F32 speedOfSound) override; }; #endif // _SFXALDEVICE_H_ diff --git a/Engine/source/sfx/openal/sfxALProvider.cpp b/Engine/source/sfx/openal/sfxALProvider.cpp deleted file mode 100644 index b3a62c4ba..000000000 --- a/Engine/source/sfx/openal/sfxALProvider.cpp +++ /dev/null @@ -1,127 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- -#include "platform/platform.h" - -#include "sfx/sfxProvider.h" -#include "sfx/openal/sfxALDevice.h" -#include "sfx/openal/aldlist.h" -#include "sfx/openal/LoadOAL.h" - -#include "core/strings/stringFunctions.h" -#include "console/console.h" -#include "core/module.h" - - -class SFXALProvider : public SFXProvider -{ -public: - - SFXALProvider() - : SFXProvider( "OpenAL" ) { dMemset(&mOpenAL,0,sizeof(mOpenAL)); mALDL = NULL; } - virtual ~SFXALProvider(); - -protected: - OPENALFNTABLE mOpenAL; - ALDeviceList *mALDL; - - struct ALDeviceInfo : SFXDeviceInfo - { - - }; - - void init() override; - -public: - SFXDevice *createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ) override; - -}; - -MODULE_BEGIN( OpenAL ) - - MODULE_INIT_BEFORE( SFX ) - MODULE_SHUTDOWN_AFTER( SFX ) - - SFXALProvider* mProvider = NULL; - - MODULE_INIT - { - mProvider = new SFXALProvider; - } - - MODULE_SHUTDOWN - { - delete mProvider; - } - -MODULE_END; - -void SFXALProvider::init() -{ - if( LoadOAL10Library( NULL, &mOpenAL ) != AL_TRUE ) - { - Con::printf( "SFXALProvider - OpenAL not available." ); - return; - } - mALDL = new ALDeviceList( mOpenAL ); - - // Did we get any devices? - if ( mALDL->GetNumDevices() < 1 ) - { - Con::printf( "SFXALProvider - No valid devices found!" ); - return; - } - - // Cool, loop through them, and caps em - //const char *deviceFormat = "OpenAL v%d.%d %s"; - - for( S32 i = 0; i < mALDL->GetNumDevices(); i++ ) - { - ALDeviceInfo* info = new ALDeviceInfo; - - //info->internalName = String( mALDL->GetInternalDeviceName( i ) ); - info->name = String( mALDL->GetDeviceName( i ) ); - - mDeviceInfo.push_back( info ); - } - - regProvider( this ); -} - -SFXALProvider::~SFXALProvider() -{ - UnloadOAL10Library(); - - if (mALDL) - delete mALDL; -} - -SFXDevice* SFXALProvider::createDevice(const String& deviceName, bool useHardware, S32 maxBuffers) -{ - ALDeviceInfo* info = dynamic_cast - (_findDeviceInfo(deviceName)); - - // Do we find one to create? - if (info) - return new SFXALDevice(this, mOpenAL, info->name, useHardware, maxBuffers); - - return NULL; -} diff --git a/Engine/source/sfx/openal/sfxALVoice.cpp b/Engine/source/sfx/openal/sfxALVoice.cpp index 12267d3c0..1894db50b 100644 --- a/Engine/source/sfx/openal/sfxALVoice.cpp +++ b/Engine/source/sfx/openal/sfxALVoice.cpp @@ -28,7 +28,7 @@ #ifdef TORQUE_DEBUG # define AL_SANITY_CHECK() \ - AssertFatal( mOpenAL.alIsSource( mSourceName ), "AL Source Sanity Check Failed!" ); + AssertFatal( alIsSource( mSourceName ), "AL Source Sanity Check Failed!" ); #else # define AL_SANITY_CHECK() #endif @@ -42,8 +42,8 @@ SFXALVoice* SFXALVoice::create( SFXALDevice* device, SFXALBuffer *buffer ) AssertFatal( buffer, "SFXALVoice::create() - Got null buffer!" ); ALuint sourceName; - device->mOpenAL.alGenSources( 1, &sourceName ); - AssertFatal( device->mOpenAL.alIsSource( sourceName ), "AL Source Sanity Check Failed!" ); + alGenSources( 1, &sourceName ); + AssertFatal( alIsSource( sourceName ), "AL Source Sanity Check Failed!" ); // Is this 3d? // Okay, this looks odd, but bear with me for a moment. AL_SOURCE_RELATIVE does NOT indicate @@ -52,34 +52,32 @@ SFXALVoice* SFXALVoice::create( SFXALDevice* device, SFXALBuffer *buffer ) // does do is dictate if the position of THIS SOURCE is relative to the listener. If AL_SOURCE_RELATIVE is AL_TRUE // and the source's position is 0, 0, 0, then the source is directly on top of the listener at all times, which is what // we want for non-3d sounds. - device->mOpenAL.alSourcei( sourceName, AL_SOURCE_RELATIVE, ( buffer->mIs3d ? AL_FALSE : AL_TRUE ) ); + alSourcei( sourceName, AL_SOURCE_RELATIVE, ( buffer->mIs3d ? AL_FALSE : AL_TRUE ) ); if( buffer->mIs3d ) - device->mOpenAL.alSourcef( sourceName, AL_ROLLOFF_FACTOR, device->mRolloffFactor ); + alSourcef( sourceName, AL_ROLLOFF_FACTOR, device->mRolloffFactor ); - SFXALVoice *voice = new SFXALVoice( device->mOpenAL, - buffer, + SFXALVoice *voice = new SFXALVoice( buffer, sourceName ); return voice; } -SFXALVoice::SFXALVoice( const OPENALFNTABLE &oalft, - SFXALBuffer *buffer, +SFXALVoice::SFXALVoice( SFXALBuffer *buffer, ALuint sourceName ) : Parent( buffer ), mSourceName( sourceName ), mResumeAtSampleOffset( -1.0f ), - mSampleOffset( 0 ), - mOpenAL( oalft ) + mSampleOffset( 0 ) { AL_SANITY_CHECK(); } SFXALVoice::~SFXALVoice() { - mOpenAL.alDeleteSources( 1, &mSourceName ); + alSourcei(mSourceName, AL_BUFFER, 0); + alDeleteSources( 1, &mSourceName ); } void SFXALVoice::_lateBindStaticBufferIfNecessary() @@ -87,9 +85,9 @@ void SFXALVoice::_lateBindStaticBufferIfNecessary() if( !mBuffer->isStreaming() ) { ALint bufferId; - mOpenAL.alGetSourcei( mSourceName, AL_BUFFER, &bufferId ); + alGetSourcei( mSourceName, AL_BUFFER, &bufferId ); if( !bufferId ) - mOpenAL.alSourcei( mSourceName, AL_BUFFER, _getBuffer()->mALBuffer ); + alSourcei( mSourceName, AL_BUFFER, _getBuffer()->mALBuffer ); } } @@ -99,7 +97,7 @@ SFXStatus SFXALVoice::_status() const AL_SANITY_CHECK(); ALint state; - mOpenAL.alGetSourcei( mSourceName, AL_SOURCE_STATE, &state ); + alGetSourcei( mSourceName, AL_SOURCE_STATE, &state ); switch( state ) { @@ -118,18 +116,15 @@ void SFXALVoice::_play() #ifdef DEBUG_SPEW Platform::outputDebugString( "[SFXALVoice] Starting playback" ); #endif -#if defined(AL_ALEXT_PROTOTYPES) - //send every voice that plays to the alauxiliary slot that has the reverb - mOpenAL.alSource3i(mSourceName, AL_AUXILIARY_SEND_FILTER, 1, 0, AL_FILTER_NULL); -#endif - mOpenAL.alSourcePlay( mSourceName ); + + alSourcePlay( mSourceName ); //WORKAROUND: Adjust play cursor for buggy OAL when resuming playback. Do this after alSourcePlay // as it is the play function that will cause the cursor to jump. if( mResumeAtSampleOffset != -1.0f ) { - mOpenAL.alSourcef( mSourceName, AL_SAMPLE_OFFSET, mResumeAtSampleOffset ); + alSourcef( mSourceName, AL_SAMPLE_OFFSET, mResumeAtSampleOffset ); mResumeAtSampleOffset = -1.0f; } } @@ -142,12 +137,12 @@ void SFXALVoice::_pause() Platform::outputDebugString( "[SFXALVoice] Pausing playback" ); #endif - mOpenAL.alSourcePause( mSourceName ); + alSourcePause( mSourceName ); //WORKAROUND: Another workaround for buggy OAL. Resuming playback of a paused source will cause the // play cursor to jump. Save the cursor so we can manually move it into position in _play(). Sigh. - mOpenAL.alGetSourcef( mSourceName, AL_SAMPLE_OFFSET, &mResumeAtSampleOffset ); + alGetSourcef( mSourceName, AL_SAMPLE_OFFSET, &mResumeAtSampleOffset ); } void SFXALVoice::_stop() @@ -158,7 +153,7 @@ void SFXALVoice::_stop() Platform::outputDebugString( "[SFXALVoice] Stopping playback" ); #endif - mOpenAL.alSourceStop( mSourceName ); + alSourceStop( mSourceName ); mSampleOffset = 0; mResumeAtSampleOffset = -1.0f; @@ -169,7 +164,7 @@ void SFXALVoice::_seek( U32 sample ) AL_SANITY_CHECK(); _lateBindStaticBufferIfNecessary(); - mOpenAL.alSourcei( mSourceName, AL_SAMPLE_OFFSET, sample ); + alSourcei( mSourceName, AL_SAMPLE_OFFSET, sample ); mResumeAtSampleOffset = -1.0f; } @@ -183,7 +178,7 @@ U32 SFXALVoice::_tell() const mBuffer->write( NULL, 0 ); ALint pos; - mOpenAL.alGetSourcei( mSourceName, AL_SAMPLE_OFFSET, &pos ); + alGetSourcei( mSourceName, AL_SAMPLE_OFFSET, &pos ); return ( pos + mSampleOffset ); } @@ -191,17 +186,17 @@ void SFXALVoice::setMinMaxDistance( F32 min, F32 max ) { AL_SANITY_CHECK(); - mOpenAL.alSourcef( mSourceName, AL_REFERENCE_DISTANCE, min ); - mOpenAL.alSourcef( mSourceName, AL_MAX_DISTANCE, max ); + alSourcef( mSourceName, AL_REFERENCE_DISTANCE, min ); + alSourcef( mSourceName, AL_MAX_DISTANCE, max ); } void SFXALVoice::play( bool looping ) { AL_SANITY_CHECK(); - mOpenAL.alSourceStop( mSourceName ); + alSourceStop( mSourceName ); if( !mBuffer->isStreaming() ) - mOpenAL.alSourcei( mSourceName, AL_LOOPING, ( looping ? AL_TRUE : AL_FALSE ) ); + alSourcei( mSourceName, AL_LOOPING, ( looping ? AL_TRUE : AL_FALSE ) ); Parent::play( looping ); } @@ -213,7 +208,7 @@ void SFXALVoice::setVelocity( const VectorF& velocity ) // Torque and OpenAL are both right handed // systems, so no coordinate flipping is needed. - mOpenAL.alSourcefv( mSourceName, AL_VELOCITY, velocity ); + alSourcefv( mSourceName, AL_VELOCITY, velocity ); } void SFXALVoice::setTransform( const MatrixF& transform ) @@ -227,34 +222,34 @@ void SFXALVoice::setTransform( const MatrixF& transform ) transform.getColumn( 3, &pos ); transform.getColumn( 1, &dir ); - mOpenAL.alSourcefv( mSourceName, AL_POSITION, pos ); - mOpenAL.alSourcefv( mSourceName, AL_DIRECTION, dir ); + alSourcefv( mSourceName, AL_POSITION, pos ); + alSourcefv( mSourceName, AL_DIRECTION, dir ); } void SFXALVoice::setVolume( F32 volume ) { AL_SANITY_CHECK(); - mOpenAL.alSourcef( mSourceName, AL_GAIN, volume ); + alSourcef( mSourceName, AL_GAIN, volume ); } void SFXALVoice::setPitch( F32 pitch ) { AL_SANITY_CHECK(); - mOpenAL.alSourcef( mSourceName, AL_PITCH, pitch ); + alSourcef( mSourceName, AL_PITCH, pitch ); } void SFXALVoice::setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume ) { AL_SANITY_CHECK(); - mOpenAL.alSourcef( mSourceName, AL_CONE_INNER_ANGLE, innerAngle ); - mOpenAL.alSourcef( mSourceName, AL_CONE_OUTER_ANGLE, outerAngle ); - mOpenAL.alSourcef( mSourceName, AL_CONE_OUTER_GAIN, outerVolume ); + alSourcef( mSourceName, AL_CONE_INNER_ANGLE, innerAngle ); + alSourcef( mSourceName, AL_CONE_OUTER_ANGLE, outerAngle ); + alSourcef( mSourceName, AL_CONE_OUTER_GAIN, outerVolume ); } void SFXALVoice::setRolloffFactor( F32 factor ) { - mOpenAL.alSourcef( mSourceName, AL_ROLLOFF_FACTOR, factor ); + alSourcef( mSourceName, AL_ROLLOFF_FACTOR, factor ); } diff --git a/Engine/source/sfx/openal/sfxALVoice.h b/Engine/source/sfx/openal/sfxALVoice.h index 2f3dd8eca..e5a2aaff6 100644 --- a/Engine/source/sfx/openal/sfxALVoice.h +++ b/Engine/source/sfx/openal/sfxALVoice.h @@ -47,8 +47,7 @@ class SFXALVoice : public SFXVoice protected: - SFXALVoice( const OPENALFNTABLE &oalft, - SFXALBuffer *buffer, + SFXALVoice( SFXALBuffer *buffer, ALuint sourceName ); ALuint mSourceName; @@ -65,8 +64,6 @@ class SFXALVoice : public SFXVoice Mutex mMutex; - const OPENALFNTABLE &mOpenAL; - /// SFXALBuffer* _getBuffer() const { @@ -104,4 +101,4 @@ class SFXALVoice : public SFXVoice void setRolloffFactor( F32 factor ) override; }; -#endif // _SFXALVOICE_H_ \ No newline at end of file +#endif // _SFXALVOICE_H_ diff --git a/Engine/source/sfx/openal/win32/LoadOAL.cpp b/Engine/source/sfx/openal/win32/LoadOAL.cpp deleted file mode 100644 index 4c1888a69..000000000 --- a/Engine/source/sfx/openal/win32/LoadOAL.cpp +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright (c) 2006, Creative Labs Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided - * that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, this list of conditions and - * the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions - * and the following disclaimer in the documentation and/or other materials provided with the distribution. - * * Neither the name of Creative Labs Inc. nor the names of its contributors may be used to endorse or - * promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include "sfx/openal/LoadOAL.h" - -HINSTANCE g_hOpenALDLL = NULL; - -ALboolean LoadOAL10Library(char *szOALFullPathName, LPOPENALFNTABLE lpOALFnTable) -{ - if (!lpOALFnTable) - return AL_FALSE; - - if (szOALFullPathName) - g_hOpenALDLL = LoadLibraryA(szOALFullPathName); - else - { -#ifdef TORQUE_DEBUG - g_hOpenALDLL = LoadLibraryA("openal32d.dll"); -#else - g_hOpenALDLL = LoadLibraryA("openal32.dll"); -#endif - } - if (!g_hOpenALDLL) - return AL_FALSE; - - memset(lpOALFnTable, 0, sizeof(OPENALFNTABLE)); - - // Get function pointers - lpOALFnTable->alEnable = (LPALENABLE)GetProcAddress(g_hOpenALDLL, "alEnable"); - if (lpOALFnTable->alEnable == NULL) - { - OutputDebugStringA("Failed to retrieve 'alEnable' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDisable = (LPALDISABLE)GetProcAddress(g_hOpenALDLL, "alDisable"); - if (lpOALFnTable->alDisable == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDisable' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsEnabled = (LPALISENABLED)GetProcAddress(g_hOpenALDLL, "alIsEnabled"); - if (lpOALFnTable->alIsEnabled == NULL) - { - OutputDebugStringA("Failed to retrieve 'alIsEnabled' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBoolean = (LPALGETBOOLEAN)GetProcAddress(g_hOpenALDLL, "alGetBoolean"); - if (lpOALFnTable->alGetBoolean == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetBoolean' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetInteger = (LPALGETINTEGER)GetProcAddress(g_hOpenALDLL, "alGetInteger"); - if (lpOALFnTable->alGetInteger == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetInteger' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetFloat = (LPALGETFLOAT)GetProcAddress(g_hOpenALDLL, "alGetFloat"); - if (lpOALFnTable->alGetFloat == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetFloat' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetDouble = (LPALGETDOUBLE)GetProcAddress(g_hOpenALDLL, "alGetDouble"); - if (lpOALFnTable->alGetDouble == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetDouble' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBooleanv = (LPALGETBOOLEANV)GetProcAddress(g_hOpenALDLL, "alGetBooleanv"); - if (lpOALFnTable->alGetBooleanv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetBooleanv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetIntegerv = (LPALGETINTEGERV)GetProcAddress(g_hOpenALDLL, "alGetIntegerv"); - if (lpOALFnTable->alGetIntegerv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetIntegerv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetFloatv = (LPALGETFLOATV)GetProcAddress(g_hOpenALDLL, "alGetFloatv"); - if (lpOALFnTable->alGetFloatv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetFloatv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetDoublev = (LPALGETDOUBLEV)GetProcAddress(g_hOpenALDLL, "alGetDoublev"); - if (lpOALFnTable->alGetDoublev == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetDoublev' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetString = (LPALGETSTRING)GetProcAddress(g_hOpenALDLL, "alGetString"); - if (lpOALFnTable->alGetString == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetString' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetError = (LPALGETERROR)GetProcAddress(g_hOpenALDLL, "alGetError"); - if (lpOALFnTable->alGetError == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetError' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsExtensionPresent = (LPALISEXTENSIONPRESENT)GetProcAddress(g_hOpenALDLL, "alIsExtensionPresent"); - if (lpOALFnTable->alIsExtensionPresent == NULL) - { - OutputDebugStringA("Failed to retrieve 'alIsExtensionPresent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetProcAddress = (LPALGETPROCADDRESS)GetProcAddress(g_hOpenALDLL, "alGetProcAddress"); - if (lpOALFnTable->alGetProcAddress == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetProcAddress' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetEnumValue = (LPALGETENUMVALUE)GetProcAddress(g_hOpenALDLL, "alGetEnumValue"); - if (lpOALFnTable->alGetEnumValue == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetEnumValue' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListeneri = (LPALLISTENERI)GetProcAddress(g_hOpenALDLL, "alListeneri"); - if (lpOALFnTable->alListeneri == NULL) - { - OutputDebugStringA("Failed to retrieve 'alListeneri' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListenerf = (LPALLISTENERF)GetProcAddress(g_hOpenALDLL, "alListenerf"); - if (lpOALFnTable->alListenerf == NULL) - { - OutputDebugStringA("Failed to retrieve 'alListenerf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListener3f = (LPALLISTENER3F)GetProcAddress(g_hOpenALDLL, "alListener3f"); - if (lpOALFnTable->alListener3f == NULL) - { - OutputDebugStringA("Failed to retrieve 'alListener3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alListenerfv = (LPALLISTENERFV)GetProcAddress(g_hOpenALDLL, "alListenerfv"); - if (lpOALFnTable->alListenerfv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alListenerfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListeneri = (LPALGETLISTENERI)GetProcAddress(g_hOpenALDLL, "alGetListeneri"); - if (lpOALFnTable->alGetListeneri == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetListeneri' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListenerf =(LPALGETLISTENERF)GetProcAddress(g_hOpenALDLL, "alGetListenerf"); - if (lpOALFnTable->alGetListenerf == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetListenerf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListener3f = (LPALGETLISTENER3F)GetProcAddress(g_hOpenALDLL, "alGetListener3f"); - if (lpOALFnTable->alGetListener3f == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetListener3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetListenerfv = (LPALGETLISTENERFV)GetProcAddress(g_hOpenALDLL, "alGetListenerfv"); - if (lpOALFnTable->alGetListenerfv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetListenerfv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGenSources = (LPALGENSOURCES)GetProcAddress(g_hOpenALDLL, "alGenSources"); - if (lpOALFnTable->alGenSources == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGenSources' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteSources = (LPALDELETESOURCES)GetProcAddress(g_hOpenALDLL, "alDeleteSources"); - if (lpOALFnTable->alDeleteSources == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDeleteSources' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsSource = (LPALISSOURCE)GetProcAddress(g_hOpenALDLL, "alIsSource"); - if (lpOALFnTable->alIsSource == NULL) - { - OutputDebugStringA("Failed to retrieve 'alIsSource' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcei = (LPALSOURCEI)GetProcAddress(g_hOpenALDLL, "alSourcei"); - if (lpOALFnTable->alSourcei == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourcei' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcef = (LPALSOURCEF)GetProcAddress(g_hOpenALDLL, "alSourcef"); - if (lpOALFnTable->alSourcef == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourcef' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSource3f = (LPALSOURCE3F)GetProcAddress(g_hOpenALDLL, "alSource3f"); - if (lpOALFnTable->alSource3f == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSource3f' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcefv = (LPALSOURCEFV)GetProcAddress(g_hOpenALDLL, "alSourcefv"); - if (lpOALFnTable->alSourcefv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourcefv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcei = (LPALGETSOURCEI)GetProcAddress(g_hOpenALDLL, "alGetSourcei"); - if (lpOALFnTable->alGetSourcei == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetSourcei' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcef = (LPALGETSOURCEF)GetProcAddress(g_hOpenALDLL, "alGetSourcef"); - if (lpOALFnTable->alGetSourcef == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetSourcef' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetSourcefv = (LPALGETSOURCEFV)GetProcAddress(g_hOpenALDLL, "alGetSourcefv"); - if (lpOALFnTable->alGetSourcefv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetSourcefv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePlayv = (LPALSOURCEPLAYV)GetProcAddress(g_hOpenALDLL, "alSourcePlayv"); - if (lpOALFnTable->alSourcePlayv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourcePlayv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceStopv = (LPALSOURCESTOPV)GetProcAddress(g_hOpenALDLL, "alSourceStopv"); - if (lpOALFnTable->alSourceStopv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourceStopv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePlay = (LPALSOURCEPLAY)GetProcAddress(g_hOpenALDLL, "alSourcePlay"); - if (lpOALFnTable->alSourcePlay == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourcePlay' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourcePause = (LPALSOURCEPAUSE)GetProcAddress(g_hOpenALDLL, "alSourcePause"); - if (lpOALFnTable->alSourcePause == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourcePause' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceStop = (LPALSOURCESTOP)GetProcAddress(g_hOpenALDLL, "alSourceStop"); - if (lpOALFnTable->alSourceStop == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourceStop' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceRewind = (LPALSOURCEREWIND)GetProcAddress(g_hOpenALDLL, "alSourceRewind"); - if (lpOALFnTable->alSourceRewind == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourceRewind' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGenBuffers = (LPALGENBUFFERS)GetProcAddress(g_hOpenALDLL, "alGenBuffers"); - if (lpOALFnTable->alGenBuffers == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGenBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDeleteBuffers = (LPALDELETEBUFFERS)GetProcAddress(g_hOpenALDLL, "alDeleteBuffers"); - if (lpOALFnTable->alDeleteBuffers == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDeleteBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alIsBuffer = (LPALISBUFFER)GetProcAddress(g_hOpenALDLL, "alIsBuffer"); - if (lpOALFnTable->alIsBuffer == NULL) - { - OutputDebugStringA("Failed to retrieve 'alIsBuffer' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alBufferData = (LPALBUFFERDATA)GetProcAddress(g_hOpenALDLL, "alBufferData"); - if (lpOALFnTable->alBufferData == NULL) - { - OutputDebugStringA("Failed to retrieve 'alBufferData' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBufferi = (LPALGETBUFFERI)GetProcAddress(g_hOpenALDLL, "alGetBufferi"); - if (lpOALFnTable->alGetBufferi == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetBufferi' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alGetBufferf = (LPALGETBUFFERF)GetProcAddress(g_hOpenALDLL, "alGetBufferf"); - if (lpOALFnTable->alGetBufferf == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetBufferf' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceQueueBuffers = (LPALSOURCEQUEUEBUFFERS)GetProcAddress(g_hOpenALDLL, "alSourceQueueBuffers"); - if (lpOALFnTable->alSourceQueueBuffers == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourceQueueBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alSourceUnqueueBuffers = (LPALSOURCEUNQUEUEBUFFERS)GetProcAddress(g_hOpenALDLL, "alSourceUnqueueBuffers"); - if (lpOALFnTable->alSourceUnqueueBuffers == NULL) - { - OutputDebugStringA("Failed to retrieve 'alSourceUnqueueBuffers' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDistanceModel = (LPALDISTANCEMODEL)GetProcAddress(g_hOpenALDLL, "alDistanceModel"); - if (lpOALFnTable->alDistanceModel == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDistanceModel' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDopplerFactor = (LPALDOPPLERFACTOR)GetProcAddress(g_hOpenALDLL, "alDopplerFactor"); - if (lpOALFnTable->alDopplerFactor == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDopplerFactor' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alDopplerVelocity = (LPALDOPPLERVELOCITY)GetProcAddress(g_hOpenALDLL, "alDopplerVelocity"); - if (lpOALFnTable->alDopplerVelocity == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDopplerVelocity' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetString = (LPALCGETSTRING)GetProcAddress(g_hOpenALDLL, "alcGetString"); - if (lpOALFnTable->alcGetString == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcGetString' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetIntegerv = (LPALCGETINTEGERV)GetProcAddress(g_hOpenALDLL, "alcGetIntegerv"); - if (lpOALFnTable->alcGetIntegerv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcGetIntegerv' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcOpenDevice = (LPALCOPENDEVICE)GetProcAddress(g_hOpenALDLL, "alcOpenDevice"); - if (lpOALFnTable->alcOpenDevice == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcOpenDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcCloseDevice = (LPALCCLOSEDEVICE)GetProcAddress(g_hOpenALDLL, "alcCloseDevice"); - if (lpOALFnTable->alcCloseDevice == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcCloseDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcCreateContext = (LPALCCREATECONTEXT)GetProcAddress(g_hOpenALDLL, "alcCreateContext"); - if (lpOALFnTable->alcCreateContext == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcCreateContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcMakeContextCurrent = (LPALCMAKECONTEXTCURRENT)GetProcAddress(g_hOpenALDLL, "alcMakeContextCurrent"); - if (lpOALFnTable->alcMakeContextCurrent == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcMakeContextCurrent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcProcessContext = (LPALCPROCESSCONTEXT)GetProcAddress(g_hOpenALDLL, "alcProcessContext"); - if (lpOALFnTable->alcProcessContext == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcProcessContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetCurrentContext = (LPALCGETCURRENTCONTEXT)GetProcAddress(g_hOpenALDLL, "alcGetCurrentContext"); - if (lpOALFnTable->alcGetCurrentContext == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcGetCurrentContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetContextsDevice = (LPALCGETCONTEXTSDEVICE)GetProcAddress(g_hOpenALDLL, "alcGetContextsDevice"); - if (lpOALFnTable->alcGetContextsDevice == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcGetContextsDevice' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcSuspendContext = (LPALCSUSPENDCONTEXT)GetProcAddress(g_hOpenALDLL, "alcSuspendContext"); - if (lpOALFnTable->alcSuspendContext == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcSuspendContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcDestroyContext = (LPALCDESTROYCONTEXT)GetProcAddress(g_hOpenALDLL, "alcDestroyContext"); - if (lpOALFnTable->alcDestroyContext == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcDestroyContext' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetError = (LPALCGETERROR)GetProcAddress(g_hOpenALDLL, "alcGetError"); - if (lpOALFnTable->alcGetError == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcGetError' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcIsExtensionPresent = (LPALCISEXTENSIONPRESENT)GetProcAddress(g_hOpenALDLL, "alcIsExtensionPresent"); - if (lpOALFnTable->alcIsExtensionPresent == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcIsExtensionPresent' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetProcAddress = (LPALCGETPROCADDRESS)GetProcAddress(g_hOpenALDLL, "alcGetProcAddress"); - if (lpOALFnTable->alcGetProcAddress == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcGetProcAddress' function address\n"); - return AL_FALSE; - } - lpOALFnTable->alcGetEnumValue = (LPALCGETENUMVALUE)GetProcAddress(g_hOpenALDLL, "alcGetEnumValue"); - if (lpOALFnTable->alcGetEnumValue == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcGetEnumValue' function address\n"); - return AL_FALSE; - } -#if defined(AL_ALEXT_PROTOTYPES) - lpOALFnTable->alGenEffects = (LPALGENEFFECTS)GetProcAddress(g_hOpenALDLL, "alGenEffects"); - if (lpOALFnTable->alGenEffects == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGenEffects' function address\n"); - } - lpOALFnTable->alEffecti = (LPALEFFECTI)GetProcAddress(g_hOpenALDLL, "alEffecti"); - if (lpOALFnTable->alEffecti == NULL) - { - OutputDebugStringA("Failed to retrieve 'alEffecti' function address\n"); - } - lpOALFnTable->alEffectiv = (LPALEFFECTIV)GetProcAddress(g_hOpenALDLL, "alEffectiv"); - if (lpOALFnTable->alEffectiv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alEffectiv' function address\n"); - } - lpOALFnTable->alEffectf = (LPALEFFECTF)GetProcAddress(g_hOpenALDLL, "alEffectf"); - if (lpOALFnTable->alEffectf == NULL) - { - OutputDebugStringA("Failed to retrieve 'alEffectf' function address\n"); - } - lpOALFnTable->alEffectfv = (LPALEFFECTFV)GetProcAddress(g_hOpenALDLL, "alEffectfv"); - if (lpOALFnTable->alEffectfv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alEffectfv' function address\n"); - } - lpOALFnTable->alGetEffecti = (LPALGETEFFECTI)GetProcAddress(g_hOpenALDLL, "alGetEffecti"); - if (lpOALFnTable->alGetEffecti == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetEffecti' function address\n"); - } - lpOALFnTable->alGetEffectiv = (LPALGETEFFECTIV)GetProcAddress(g_hOpenALDLL, "alGetEffectiv"); - if (lpOALFnTable->alGetEffectiv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetEffectiv' function address\n"); - } - lpOALFnTable->alGetEffectf = (LPALGETEFFECTF)GetProcAddress(g_hOpenALDLL, "alGetEffectf"); - if (lpOALFnTable->alGetEffectf == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetEffectf' function address\n"); - } - lpOALFnTable->alGetEffectfv = (LPALGETEFFECTFV)GetProcAddress(g_hOpenALDLL, "alGetEffectfv"); - if (lpOALFnTable->alGetEffectfv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetEffectfv' function address\n"); - } - - lpOALFnTable->alDeleteEffects = (LPALDELETEEFFECTS)GetProcAddress(g_hOpenALDLL, "alDeleteEffects"); - if (lpOALFnTable->alDeleteEffects == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDeleteEffects' function address\n"); - } - lpOALFnTable->alIsEffect = (LPALISEFFECT)GetProcAddress(g_hOpenALDLL, "alIsEffect"); - if (lpOALFnTable->alIsEffect == NULL) - { - OutputDebugStringA("Failed to retrieve 'alIsEffect' function address\n"); - } - lpOALFnTable->alAuxiliaryEffectSlotf = (LPALAUXILIARYEFFECTSLOTF)GetProcAddress(g_hOpenALDLL, "alAuxiliaryEffectSlotf"); - if (lpOALFnTable->alAuxiliaryEffectSlotf == NULL) - { - OutputDebugStringA("Failed to retrieve 'alAuxiliaryEffectSlotf' function address\n"); - } - lpOALFnTable->alAuxiliaryEffectSlotfv = (LPALAUXILIARYEFFECTSLOTFV)GetProcAddress(g_hOpenALDLL, "alAuxiliaryEffectSlotfv"); - if (lpOALFnTable->alAuxiliaryEffectSlotfv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alAuxiliaryEffectSlotfv' function address\n"); - } - lpOALFnTable->alAuxiliaryEffectSloti = (LPALAUXILIARYEFFECTSLOTI)GetProcAddress(g_hOpenALDLL, "alAuxiliaryEffectSloti"); - if (lpOALFnTable->alAuxiliaryEffectSloti == NULL) - { - OutputDebugStringA("Failed to retrieve 'alAuxiliaryEffectSloti' function address\n"); - } - lpOALFnTable->alAuxiliaryEffectSlotiv = (LPALAUXILIARYEFFECTSLOTIV)GetProcAddress(g_hOpenALDLL, "alAuxiliaryEffectSlotiv"); - if (lpOALFnTable->alAuxiliaryEffectSlotiv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alAuxiliaryEffectSlotiv' function address\n"); - } - lpOALFnTable->alIsAuxiliaryEffectSlot = (LPALISAUXILIARYEFFECTSLOT)GetProcAddress(g_hOpenALDLL, "alIsAuxiliaryEffectSlot"); - if (lpOALFnTable->alIsAuxiliaryEffectSlot == NULL) - { - OutputDebugStringA("Failed to retrieve 'alIsAuxiliaryEffectSlot' function address\n"); - } - lpOALFnTable->alGenAuxiliaryEffectSlots = (LPALGENAUXILIARYEFFECTSLOTS)GetProcAddress(g_hOpenALDLL, "alGenAuxiliaryEffectSlots"); - if (lpOALFnTable->alGenAuxiliaryEffectSlots == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGenAuxiliaryEffectSlots' function address\n"); - } - lpOALFnTable->alDeleteAuxiliaryEffectSlots = (LPALDELETEAUXILIARYEFFECTSLOTS)GetProcAddress(g_hOpenALDLL, "alDeleteAuxiliaryEffectSlots"); - if (lpOALFnTable->alDeleteAuxiliaryEffectSlots == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDeleteAuxiliaryEffectSlots' function address\n"); - } - lpOALFnTable->alGetAuxiliaryEffectSlotf = (LPALGETAUXILIARYEFFECTSLOTF)GetProcAddress(g_hOpenALDLL, "alGetAuxiliaryEffectSlotf"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotf == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetAuxiliaryEffectSlotf' function address\n"); - } - lpOALFnTable->alGetAuxiliaryEffectSlotfv = (LPALGETAUXILIARYEFFECTSLOTFV)GetProcAddress(g_hOpenALDLL, "alGetAuxiliaryEffectSlotfv"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotfv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetAuxiliaryEffectSlotfv' function address\n"); - } - lpOALFnTable->alGetAuxiliaryEffectSloti = (LPALGETAUXILIARYEFFECTSLOTI)GetProcAddress(g_hOpenALDLL, "alGetAuxiliaryEffectSloti"); - if (lpOALFnTable->alGetAuxiliaryEffectSloti == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetAuxiliaryEffectSloti' function address\n"); - } - lpOALFnTable->alGetAuxiliaryEffectSlotiv = (LPALGETAUXILIARYEFFECTSLOTIV)GetProcAddress(g_hOpenALDLL, "alGetAuxiliaryEffectSlotiv"); - if (lpOALFnTable->alGetAuxiliaryEffectSlotiv == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGetAuxiliaryEffectSlotiv' function address\n"); - } - lpOALFnTable->alSource3i = (LPALSOURCE3I)GetProcAddress(g_hOpenALDLL, "alSource3i"); - - lpOALFnTable->alGenFilters = (LPALGENFILTERS)GetProcAddress(g_hOpenALDLL, "alGenFilters"); - if (lpOALFnTable->alGenFilters == NULL) - { - OutputDebugStringA("Failed to retrieve 'alGenFilters' function address\n"); - return AL_FALSE; - } - - lpOALFnTable->alDeleteFilters = (LPALDELETEFILTERS)GetProcAddress(g_hOpenALDLL, "alDeleteFilters"); - if (lpOALFnTable->alGenFilters == NULL) - { - OutputDebugStringA("Failed to retrieve 'alDeleteFilters' function address\n"); - return AL_FALSE; - } - - lpOALFnTable->alFilteri = (LPALFILTERI)GetProcAddress(g_hOpenALDLL, "alFilteri"); - if (lpOALFnTable->alGenFilters == NULL) - { - OutputDebugStringA("Failed to retrieve 'alFilteri' function address\n"); - return AL_FALSE; - } - - lpOALFnTable->alcGetStringiSOFT = (LPALCGETSTRINGISOFT)GetProcAddress(g_hOpenALDLL, "alcGetStringiSOFT"); - if (lpOALFnTable->alcGetStringiSOFT == NULL) - { - OutputDebugStringA("Failed to retrieve 'alcGetStringiSOFT' function address\n"); - return AL_FALSE; - } - -#endif - return AL_TRUE; -} - -ALvoid UnloadOAL10Library() -{ - // Unload the dll - if (g_hOpenALDLL) - { - FreeLibrary(g_hOpenALDLL); - g_hOpenALDLL = NULL; - } -} diff --git a/Engine/source/sfx/sfxAmbience.cpp b/Engine/source/sfx/sfxAmbience.cpp index 285ffc03a..6074369a5 100644 --- a/Engine/source/sfx/sfxAmbience.cpp +++ b/Engine/source/sfx/sfxAmbience.cpp @@ -85,6 +85,7 @@ SFXAmbience::ChangeSignal SFXAmbience::smChangeSignal; SFXAmbience::SFXAmbience() : mDopplerFactor( 0.5f ), mRolloffFactor( 1.f ), + mSpeedOfSound(343.3f), mEnvironment( NULL ) { dMemset( mState, 0, sizeof( mState ) ); @@ -112,6 +113,10 @@ void SFXAmbience::initPersistFields() "The factor to apply to the doppler affect in this space.\n" "Defaults to 0.5.\n\n" "@ref SFXSource_doppler" ); + addFieldV("speedOfSound", TypeRangedF32, Offset(mSpeedOfSound, SFXAmbience), &CommonValidators::PositiveFloat, + "The speed of sound in this space.\n" + "Defaults to 343.3.\n\n" + "@ref SFXSource_speedofsound"); addField( "states", TypeSFXStateName, Offset( mState, SFXAmbience ), MaxStates, "States to activate when the ambient zone is entered.\n" @@ -177,6 +182,7 @@ void SFXAmbience::packData( BitStream* stream ) stream->write( mRolloffFactor ); stream->write( mDopplerFactor ); + stream->write(mSpeedOfSound); for( U32 i = 0; i < MaxStates; ++ i ) sfxWrite( stream, mState[ i ] ); @@ -193,6 +199,7 @@ void SFXAmbience::unpackData( BitStream* stream ) stream->read( &mRolloffFactor ); stream->read( &mDopplerFactor ); + stream->read(&mSpeedOfSound); for( U32 i = 0; i < MaxStates; ++ i ) sfxRead( stream, &mState[ i ] ); diff --git a/Engine/source/sfx/sfxAmbience.h b/Engine/source/sfx/sfxAmbience.h index bd36a1547..d429e5570 100644 --- a/Engine/source/sfx/sfxAmbience.h +++ b/Engine/source/sfx/sfxAmbience.h @@ -61,6 +61,9 @@ class SFXAmbience : public SimDataBlock /// Doppler shift factor for this space. F32 mDopplerFactor; + + /// Speed of sound for this space. + F32 mSpeedOfSound; /// Rolloff factor for this space. Only applies to logarithmic distance model. F32 mRolloffFactor; @@ -90,6 +93,8 @@ class SFXAmbience : public SimDataBlock /// Return the doppler shift factor to apply in this space. F32 getDopplerFactor() const { return mDopplerFactor; } + + F32 getSpeedOfSound() const { return mSpeedOfSound; } /// Return the reverb environment of the ambient space. SFXEnvironment* getEnvironment() const { return mEnvironment; } diff --git a/Engine/source/sfx/sfxCommon.h b/Engine/source/sfx/sfxCommon.h index 784f612f6..22ff258c1 100644 --- a/Engine/source/sfx/sfxCommon.h +++ b/Engine/source/sfx/sfxCommon.h @@ -24,25 +24,25 @@ #define _SFXCOMMON_H_ #ifndef _PLATFORM_H_ - #include "platform/platform.h" +#include "platform/platform.h" #endif #ifndef _MMATHFN_H_ - #include "math/mMathFn.h" +#include "math/mMathFn.h" #endif #ifndef _MRANDOM_H_ - #include "math/mRandom.h" +#include "math/mRandom.h" #endif #ifndef _MMATRIX_H_ - #include "math/mMatrix.h" +#include "math/mMatrix.h" #endif #ifndef _MPOINT3_H_ - #include "math/mPoint3.h" +#include "math/mPoint3.h" #endif #ifndef _TYPETRAITS_H_ - #include "platform/typetraits.h" +#include "platform/typetraits.h" #endif #ifndef _DYNAMIC_CONSOLETYPES_H_ - #include "console/dynamicTypes.h" +#include "console/dynamicTypes.h" #endif @@ -51,13 +51,37 @@ class SFXEnvironment; class SFXPlayList; +//----------------------------------------------------------------------------- +// SFXProviderType. +//----------------------------------------------------------------------------- +enum SFXProviderType +{ + OpenAL, + XAudio, + DirectSound, + NullProvider, + SFXProviderType_Count +}; +DefineEnumType(SFXProviderType); + +//----------------------------------------------------------------------------- +// SFXDeviceType. +//----------------------------------------------------------------------------- +enum SFXDeviceType +{ + Output, + Input, + SFXDeviceType_Count +}; +DefineEnumType(SFXDeviceType); + //----------------------------------------------------------------------------- // SFXStatus. //----------------------------------------------------------------------------- /// The sound playback state. -enum SFXStatus +enum SFXStatus { /// Initial state; no operation yet performed on sound. SFXStatusNull, @@ -83,23 +107,23 @@ enum SFXStatus SFXStatusTransition, }; -DefineEnumType( SFXStatus ); +DefineEnumType(SFXStatus); -inline const char* SFXStatusToString( SFXStatus status ) +inline const char* SFXStatusToString(SFXStatus status) { - switch ( status ) + switch (status) { - case SFXStatusPlaying: return "playing"; - case SFXStatusStopped: return "stopped"; - case SFXStatusPaused: return "paused"; - case SFXStatusBlocked: return "blocked"; - case SFXStatusTransition: return "transition"; - - case SFXStatusNull: - default: ; + case SFXStatusPlaying: return "playing"; + case SFXStatusStopped: return "stopped"; + case SFXStatusPaused: return "paused"; + case SFXStatusBlocked: return "blocked"; + case SFXStatusTransition: return "transition"; + + case SFXStatusNull: + default:; } - + return "null"; } @@ -135,12 +159,12 @@ enum SFXChannel SFXChannelUser1, SFXChannelUser2, SFXChannelUser3, - + /// Total number of animatable channels. SFX_NUM_CHANNELS }; -DefineEnumType( SFXChannel ); +DefineEnumType(SFXChannel); //----------------------------------------------------------------------------- @@ -156,7 +180,7 @@ enum SFXDistanceModel SFXDistanceModelExponent, /// exponential falloff for distance attenuation. }; -DefineEnumType( SFXDistanceModel ); +DefineEnumType(SFXDistanceModel); /// Compute the distance attenuation based on the given distance model. /// @@ -167,46 +191,52 @@ DefineEnumType( SFXDistanceModel ); /// @param rolloffFactor Rolloff curve scale factor. /// /// @return The attenuated volume. -inline F32 SFXDistanceAttenuation( SFXDistanceModel model, F32 minDistance, F32 maxDistance, F32 distance, F32 volume, F32 rolloffFactor ) +inline F32 SFXDistanceAttenuation(SFXDistanceModel model, F32 minDistance, F32 maxDistance, F32 distance, F32 volume, F32 rolloffFactor) { F32 gain = 1.0f; - - switch( model ) + + switch (model) { - case SFXDistanceModelLinear: - - distance = getMax( distance, minDistance ); - distance = getMin( distance, maxDistance ); - - gain = ( 1 - ( distance - minDistance ) / ( maxDistance - minDistance ) ); - break; - - case SFXDistanceModelLogarithmic: - - distance = getMax( distance, minDistance ); - distance = getMin( distance, maxDistance ); - - gain = minDistance / ( minDistance + rolloffFactor * ( distance - minDistance ) ); - break; + case SFXDistanceModelLinear: - ///create exponential distance model - case SFXDistanceModelExponent: - distance = getMax(distance, minDistance); - distance = getMin(distance, maxDistance); + distance = getMax(distance, minDistance); + distance = getMin(distance, maxDistance); + + gain = (1 - rolloffFactor * (distance - minDistance) / (maxDistance - minDistance)); + break; + + case SFXDistanceModelLogarithmic: + + distance = getMax(distance, minDistance); + distance = getMin(distance, maxDistance); + + gain = minDistance / (minDistance + rolloffFactor * (distance - minDistance)); + break; + + ///create exponential distance model + case SFXDistanceModelExponent: + distance = getMax(distance, minDistance); + distance = getMin(distance, maxDistance); + + gain = pow((distance / minDistance), (-rolloffFactor)); + break; - gain = pow((distance / minDistance), (-rolloffFactor)); - break; - } - - return ( volume * gain ); + + return (volume * gain); } //----------------------------------------------------------------------------- // SFXFormat. //----------------------------------------------------------------------------- - +enum SFXSampleType { + Sample_Int8, + Sample_Int16, + Sample_Float, + Sample_IMA4, + Sample_MSADPCM +}; /// This class defines the various types of sound data that may be /// used in the sound system. @@ -216,101 +246,111 @@ inline F32 SFXDistanceAttenuation( SFXDistanceModel model, F32 minDistance, F32 /// channel. class SFXFormat { - protected: +protected: - /// The number of sound channels in the data. - U8 mChannels; + /// The number of sound channels in the data. + U8 mChannels; - /// The number of bits per sound sample. - U8 mBitsPerSample; + /// The number of bits per sound sample. + U8 mBitsPerSample; - /// The frequency in samples per second. - U32 mSamplesPerSecond; + /// The frequency in samples per second. + U32 mSamplesPerSecond; - public: + SFXSampleType mSampleType; +public: - SFXFormat( U8 channels = 0, - U8 bitsPerSample = 0, - U32 samplesPerSecond = 0 ) - : mChannels( channels ), - mBitsPerSample( bitsPerSample ), - mSamplesPerSecond( samplesPerSecond ) - {} + SFXFormat(U8 channels = 0, + U8 bitsPerSample = 0, + U32 samplesPerSecond = 0) + : mChannels(channels), + mBitsPerSample(bitsPerSample), + mSamplesPerSecond(samplesPerSecond), + mSampleType(SFXSampleType::Sample_Int16) + { + } - /// Copy constructor. - SFXFormat( const SFXFormat &format ) - : mChannels( format.mChannels ), - mBitsPerSample( format.mBitsPerSample ), - mSamplesPerSecond( format.mSamplesPerSecond ) - {} + /// Copy constructor. + SFXFormat(const SFXFormat& format) + : mChannels(format.mChannels), + mBitsPerSample(format.mBitsPerSample), + mSamplesPerSecond(format.mSamplesPerSecond), + mSampleType(format.mSampleType) + { + } - public: +public: - /// Sets the format. - void set( U8 channels, - U8 bitsPerSample, - U32 samplesPerSecond ) - { - mChannels = channels; - mBitsPerSample = bitsPerSample; - mSamplesPerSecond = samplesPerSecond; - } + /// Sets the format. + void set(U8 channels, + U8 bitsPerSample, + U32 samplesPerSecond, + SFXSampleType sampleType = Sample_Int16) + { + mChannels = channels; + mBitsPerSample = bitsPerSample; + mSamplesPerSecond = samplesPerSecond; + mSampleType = sampleType; + } - /// Comparision between formats. - bool operator == ( const SFXFormat& format ) const - { - return mChannels == format.mChannels && - mBitsPerSample == format.mBitsPerSample && - mSamplesPerSecond == format.mSamplesPerSecond; - } + /// Comparision between formats. + bool operator == (const SFXFormat& format) const + { + return mChannels == format.mChannels && + mBitsPerSample == format.mBitsPerSample && + mSamplesPerSecond == format.mSamplesPerSecond && + mSampleType == format.mSampleType; + } - /// Returns the number of sound channels. - U8 getChannels() const { return mChannels; } + /// Returns the number of sound channels. + U8 getChannels() const { return mChannels; } - /// Returns true if there is a single sound channel. - bool isMono() const { return mChannels == 1; } + /// Returns true if there is a single sound channel. + bool isMono() const { return mChannels == 1; } - /// Is true if there are two sound channels. - bool isStereo() const { return mChannels == 2; } + /// Is true if there are two sound channels. + bool isStereo() const { return mChannels == 2; } - /// Is true if there are more than two sound channels. - bool isMultiChannel() const { return mChannels > 2; } + /// Is true if there are more than two sound channels. + bool isMultiChannel() const { return mChannels > 2; } - /// - U32 getSamplesPerSecond() const { return mSamplesPerSecond; } + /// + U32 getSamplesPerSecond() const { return mSamplesPerSecond; } - /// The bits of data per channel. - U8 getBitsPerChannel() const { return mBitsPerSample / mChannels; } + /// The bits of data per channel. + U8 getBitsPerChannel() const { return mBitsPerSample / mChannels; } - /// The number of bytes of data per channel. - U8 getBytesPerChannel() const { return getBitsPerChannel() / 8; } + /// The number of bytes of data per channel. + U8 getBytesPerChannel() const { return getBitsPerChannel() / 8; } - /// The number of bits per sound sample. - U8 getBitsPerSample() const { return mBitsPerSample; } + /// The number of bits per sound sample. + U8 getBitsPerSample() const { return mBitsPerSample; } - /// The number of bytes of data per sample. - /// @note Be aware that this comprises all channels. - U8 getBytesPerSample() const { return mBitsPerSample / 8; } + SFXSampleType getSampleType() const { return mSampleType; } - /// Returns the duration from the sample count. - U32 getDuration( U32 samples ) const - { - // Use 64bit types to avoid overflow during division. - return ( (U64)samples * (U64)1000 ) / (U64)mSamplesPerSecond; - } + /// The number of bytes of data per sample. + /// @note Be aware that this comprises all channels. + U8 getBytesPerSample() const { return mBitsPerSample / 8; } - /// - U32 getSampleCount( U32 ms ) const - { - return U64( mSamplesPerSecond ) * U64( ms ) / U64( 1000 ); - } + /// Returns the duration from the sample count. + U32 getDuration(U32 samples) const + { + // Use 64bit types to avoid overflow during division. + return ((U64)samples * (U64)1000) / (U64)mSamplesPerSecond; + } - /// Returns the data length in bytes. - U32 getDataLength( U32 ms ) const - { - U32 bytes = ( ( (U64)ms * (U64)mSamplesPerSecond ) * (U64)getBytesPerSample() ) / (U64)1000; - return bytes; - } + /// + U32 getSampleCount(U32 ms) const + { + return U64(mSamplesPerSecond) * U64(ms) / U64(1000); + } + + /// Returns the data length in bytes. + U32 getDataLength(U32 ms) const + { + U32 bytes = (((U64)ms * (U64)mSamplesPerSecond) * (U64)getBytesPerSample()) / (U64)1000; + return bytes; + } }; @@ -363,8 +403,8 @@ public: flGain = 0.0f; flGainHF = 0.0f; flGainLF = 0.0000f; - flDecayTime = 0.0f; - flDecayHFRatio = 0.0f; + flDecayTime = 0.1f; + flDecayHFRatio = 0.1f; flDecayLFRatio = 0.0f; flReflectionsGain = 0.0f; flReflectionsDelay = 0.0f; @@ -372,15 +412,17 @@ public: flLateReverbGain = 0.0f; flLateReverbDelay = 0.0f; dMemset(flLateReverbPan, 0, sizeof(flLateReverbPan)); - flEchoTime = 0.0f; + flEchoTime = 0.075f; flEchoDepth = 0.0f; - flModulationTime = 0.0f; + flModulationTime = 0.04f; flModulationDepth = 0.0f; - flAirAbsorptionGainHF = 0.0f; + flAirAbsorptionGainHF = 0.892f; flHFReference = 0.0f; flLFReference = 0.0f; flRoomRolloffFactor = 0.0f; iDecayHFLimit = 0; + + validate(); } void validate() @@ -528,31 +570,33 @@ public: /// class SFXListenerProperties { - public: - - typedef void Parent; - - /// Position and orientation of the listener. - MatrixF mTransform; - - /// - Point3F mVelocity; +public: - SFXListenerProperties() - : mTransform( true ), - mVelocity( 0.0f, 0.0f, 0.0f ) {} - - SFXListenerProperties( const MatrixF& transform, const Point3F& velocity ) - : mTransform( transform ), - mVelocity( velocity ) {} - - /// - const MatrixF& getTransform() const { return mTransform; } - MatrixF& getTransform() { return mTransform; } - - /// - const Point3F& getVelocity() const { return mVelocity; } - Point3F& getVelocity() { return mVelocity; } + typedef void Parent; + + /// Position and orientation of the listener. + MatrixF mTransform; + + /// + Point3F mVelocity; + + SFXListenerProperties() + : mTransform(true), + mVelocity(0.0f, 0.0f, 0.0f) { + } + + SFXListenerProperties(const MatrixF& transform, const Point3F& velocity) + : mTransform(transform), + mVelocity(velocity) { + } + + /// + const MatrixF& getTransform() const { return mTransform; } + MatrixF& getTransform() { return mTransform; } + + /// + const Point3F& getVelocity() const { return mVelocity; } + Point3F& getVelocity() { return mVelocity; } }; @@ -564,29 +608,30 @@ class SFXListenerProperties /// class SFXMaterialProperties { - public: - - typedef void Parent; - - /// - bool mDoubleSided; - - /// - F32 mDirectOcclusion; - - /// - F32 mReverbOcclusion; - - SFXMaterialProperties() - : mDoubleSided( false ), - mDirectOcclusion( 0.5f ), - mReverbOcclusion( 0.5f ) {} - - void validate() - { - mDirectOcclusion = mClampF( mDirectOcclusion, 0.0f, 1.0f ); - mReverbOcclusion = mClampF( mReverbOcclusion, 0.0f, 1.0f ); - } +public: + + typedef void Parent; + + /// + bool mDoubleSided; + + /// + F32 mDirectOcclusion; + + /// + F32 mReverbOcclusion; + + SFXMaterialProperties() + : mDoubleSided(false), + mDirectOcclusion(0.5f), + mReverbOcclusion(0.5f) { + } + + void validate() + { + mDirectOcclusion = mClampF(mDirectOcclusion, 0.0f, 1.0f); + mReverbOcclusion = mClampF(mReverbOcclusion, 0.0f, 1.0f); + } }; @@ -600,28 +645,28 @@ template< S32 NUM_VALUES > struct SFXVariantFloat { /// Base value. - F32 mValue[ NUM_VALUES ]; - + F32 mValue[NUM_VALUES]; + /// Variance of value. Final value will be /// /// mClampF( randF( mValue + mVariance[ 0 ], mValue + mVariance[ 1 ] ), min, max ) /// /// with min and max being dependent on the context of the value. - F32 mVariance[ NUM_VALUES ][ 2 ]; - - F32 getValue( U32 index = 0, F32 min = TypeTraits< F32 >::MIN, F32 max = TypeTraits< F32 >::MAX ) const + F32 mVariance[NUM_VALUES][2]; + + F32 getValue(U32 index = 0, F32 min = TypeTraits< F32 >::MIN, F32 max = TypeTraits< F32 >::MAX) const { - AssertFatal( index < NUM_VALUES, "SFXVariantFloat::getValue() - index out of range!" ); - - return mClampF( gRandGen.randF( mValue[ index ] + mVariance[ index ][ 0 ], - mValue[ index ] + mVariance[ index ][ 1 ] ), - min, max ); + AssertFatal(index < NUM_VALUES, "SFXVariantFloat::getValue() - index out of range!"); + + return mClampF(gRandGen.randF(mValue[index] + mVariance[index][0], + mValue[index] + mVariance[index][1]), + min, max); } - + void validate() { - for( U32 i = 0; i < NUM_VALUES; ++ i ) - mVariance[ i ][ 0 ] = getMin( mVariance[ i ][ 0 ], mVariance[ i ][ 1 ] ); + for (U32 i = 0; i < NUM_VALUES; ++i) + mVariance[i][0] = getMin(mVariance[i][0], mVariance[i][1]); } }; diff --git a/Engine/source/sfx/sfxDevice.cpp b/Engine/source/sfx/sfxDevice.cpp index a069b0564..5c08eeb2e 100644 --- a/Engine/source/sfx/sfxDevice.cpp +++ b/Engine/source/sfx/sfxDevice.cpp @@ -29,20 +29,36 @@ #include "console/consoleTypes.h" -//----------------------------------------------------------------------------- +S32 SFXDevice::smUpdateInterval = SFXInternal::DEFAULT_UPDATE_INTERVAL; +S32 SFXDevice::smDeviceFrequency = 44100; +S8 SFXDevice::smDeviceBitrate = 16; +bool SFXDevice::smDeviceHRTF = false; -SFXDevice::SFXDevice( const String& name, SFXProvider* provider, bool useHardware, S32 maxBuffers ) - : mName( name ), - mProvider( provider ), - mUseHardware( useHardware ), - mMaxBuffers( maxBuffers ), - mCaps( 0 ), - mStatNumBuffers( 0 ), +void SFXDevice::initConsole() +{ + // Add global preferences for sfx devices. + Con::addVariable("$pref::SFX::bitrate", TypeS8, &smDeviceBitrate, + "The devices bitrate.\n" + "@ingroup SFX\n"); + + Con::addVariable("$pref::SFX::frequency", TypeS32, &smDeviceFrequency, + "The devices frequency.\n" + "@ingroup SFX\n"); + + Con::addVariable("$pref::SFX::useHRTF", TypeBool, &smDeviceHRTF, + "The device uses hrtf.\n" + "@ingroup SFX\n"); + + Con::addVariable("$pref::SFX::updateInterval", TypeS32, &smUpdateInterval, + "The update interval.\n" + "@ingroup SFX\n"); +} + +SFXDevice::SFXDevice() + : mStatNumBuffers( 0 ), mStatNumVoices( 0 ), mStatNumBufferBytes( 0 ) { - AssertFatal( provider, "We must have a provider pointer on device creation!" ); - VECTOR_SET_ASSOCIATION( mBuffers ); VECTOR_SET_ASSOCIATION( mVoices ); @@ -54,8 +70,6 @@ SFXDevice::SFXDevice( const String& name, SFXProvider* provider, bool useHardwar Con::addVariable( "SFX::Device::numBufferBytes", TypeS32, &mStatNumBufferBytes ); } -//----------------------------------------------------------------------------- - SFXDevice::~SFXDevice() { Con::removeVariable( "SFX::Device::numBuffers" ); @@ -78,13 +92,13 @@ void SFXDevice::_releaseAllResources() ThreadSafeRef< SFXUpdateThread > sfxThread = UPDATE_THREAD(); if( sfxThread != NULL ) { - gUpdateThread = NULL; // Kill the global reference. - sfxThread->stop(); sfxThread->triggerUpdate(); sfxThread->join(); sfxThread = NULL; + gUpdateThread = NULL; // Kill the global reference. + } // Clean up voices. Do this before cleaning up buffers so that @@ -92,9 +106,11 @@ void SFXDevice::_releaseAllResources() // get released properly. SFXVoice::smVoiceDestroyedSignal.remove( this, &SFXDevice::_removeVoice ); - for( VoiceIterator voice = mVoices.begin(); - voice != mVoices.end(); voice++ ) - ( *voice )->destroySelf(); + for (VoiceIterator voice = mVoices.begin(); voice != mVoices.end(); voice++) + { + (*voice)->stop(); + (*voice)->destroySelf(); + } mVoices.clear(); // Clean up buffers. diff --git a/Engine/source/sfx/sfxDevice.h b/Engine/source/sfx/sfxDevice.h index a2389f587..45d1df766 100644 --- a/Engine/source/sfx/sfxDevice.h +++ b/Engine/source/sfx/sfxDevice.h @@ -23,21 +23,19 @@ #ifndef _SFXDEVICE_H_ #define _SFXDEVICE_H_ +#ifndef _SFXPROVIDER_H_ +#include "sfx/sfxProvider.h" +#endif #ifndef _PLATFORM_H_ #include "platform/platform.h" #endif #ifndef _TVECTOR_H_ #include "core/util/tVector.h" #endif -#ifndef _SFXCOMMON_H_ - #include "sfx/sfxCommon.h" -#endif #ifndef _THREADSAFEREF_H_ #include "platform/threads/threadSafeRefCount.h" #endif - -class SFXProvider; class SFXListener; class SFXBuffer; class SFXVoice; @@ -46,8 +44,6 @@ class SFXDevice; class SFXStream; class SFXDescription; - - /// Abstract base class for back-end sound API implementations. class SFXDevice { @@ -58,13 +54,26 @@ class SFXDevice /// Device capability flags. enum ECaps { - CAPS_Reverb = BIT( 0 ), ///< Device supports reverb environments. - CAPS_VoiceManagement = BIT( 1 ), ///< Device manages voices on its own; deactivates virtualization code in SFX system. - CAPS_Occlusion = BIT( 2 ), ///< Device has its own sound occlusion handling (SFXOcclusionManager). - CAPS_DSPEffects = BIT( 3 ), ///< Device implements DSP effects (SFXDSPManager). - CAPS_MultiListener = BIT( 4 ), ///< Device supports multiple listeners. + CAPS_Reverb = BIT(0), ///< Device supports reverb environments. + CAPS_VoiceManagement = BIT(1), ///< Device manages voices on its own; deactivates virtualization code in SFX system. + CAPS_Occlusion = BIT(2), ///< Device has its own sound occlusion handling (SFXOcclusionManager). + CAPS_DSPEffects = BIT(3), ///< Device implements DSP effects (SFXDSPManager). + CAPS_MultiListener = BIT(4), ///< Device supports multiple listeners. + CAPS_HRTF = BIT(5), ///< Device supports HRTF (3D audio positioning). + CAPS_Float32 = BIT(6), ///< Device supports 32-bit float playback. + CAPS_MonoStereo = BIT(7), ///< Device supports mono/stereo output modes. }; + + static void initConsole(); + static S32 smUpdateInterval; + /// The device frequency, used when reading in buffers for the device. + static S32 smDeviceFrequency; + /// The device bitrate. + static S8 smDeviceBitrate; + /// Does the device use hrtf + static bool smDeviceHRTF; + protected: typedef Vector< SFXBuffer* > BufferVector; @@ -73,13 +82,11 @@ class SFXDevice typedef BufferVector::iterator BufferIterator; typedef VoiceVector::iterator VoiceIterator; - SFXDevice( const String& name, SFXProvider* provider, bool useHardware, S32 maxBuffers ); - /// The name of this device. String mName; /// The provider which created this device. - SFXProvider* mProvider; + SFXProvider mProvider; /// Should the device try to use hardware processing. bool mUseHardware; @@ -125,11 +132,12 @@ class SFXDevice void _releaseAllResources(); public: - + SFXDevice(); virtual ~SFXDevice(); /// Returns the provider which created this device. - SFXProvider* getProvider() const { return mProvider; } + virtual const SFXProvider& getProvider() { return mProvider; } + virtual void setProvider(const SFXProvider& provider) { mProvider = provider; } /// Is the device set to use hardware processing. bool getUseHardware() const { return mUseHardware; } @@ -174,6 +182,9 @@ public: /// Set the scale factor to use for doppler effects on 3D sounds. virtual void setDopplerFactor( F32 factor ) {} + + /// Set the speed of sound for the device. + virtual void setSpeedOfSound(F32 speedOfSound) {} /// Set the rolloff scale factor for distance attenuation of 3D sounds. virtual void setRolloffFactor( F32 factor ) {} diff --git a/Engine/source/sfx/sfxProvider.cpp b/Engine/source/sfx/sfxProvider.cpp deleted file mode 100644 index 73de67d44..000000000 --- a/Engine/source/sfx/sfxProvider.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "core/strings/stringFunctions.h" -#include "sfx/sfxProvider.h" - -SFXProvider* SFXProvider::smProviders = NULL; -Vector SFXProvider::sAllProviders( __FILE__, __LINE__ ); - -SFXProvider* SFXProvider::findProvider( String providerName ) -{ - if( providerName.isEmpty() ) - return NULL; - - SFXProvider* curr = smProviders; - for ( ; curr != NULL; curr = curr->mNextProvider ) - { - if( curr->getName().equal( providerName, String::NoCase ) ) - return curr; - } - - return NULL; -} - -void SFXProvider::regProvider( SFXProvider* provider ) -{ - AssertFatal( provider, "Got null provider!" ); - AssertFatal( findProvider( provider->getName() ) == NULL, "Can't register provider twice!" ); - AssertFatal( provider->mNextProvider == NULL, "Can't register provider twice!" ); - - SFXProvider* oldHead = smProviders; - smProviders = provider; - provider->mNextProvider = oldHead; -} - -SFXProvider::SFXProvider( const String& name ) - : mNextProvider( NULL ), - mName( name ) -{ - VECTOR_SET_ASSOCIATION( mDeviceInfo ); - - sAllProviders.push_back( this ); -} - -void SFXProvider::initializeAllProviders() -{ - - for (U32 i = 0; i < sAllProviders.size(); i++) - sAllProviders[i]->init(); - -} - -SFXProvider::~SFXProvider() -{ - SFXDeviceInfoVector::iterator iter = mDeviceInfo.begin(); - for ( ; iter != mDeviceInfo.end(); iter++ ) - delete *iter; -} - -SFXDeviceInfo* SFXProvider::_findDeviceInfo( const String& deviceName ) -{ - SFXDeviceInfoVector::iterator iter = mDeviceInfo.begin(); - for ( ; iter != mDeviceInfo.end(); iter++ ) - { - if( deviceName.equal( ( *iter )->name, String::NoCase ) ) - return *iter; - } - - // If not found and deviceName is empty, - // return first (default) device. - - if( deviceName.isEmpty() && mDeviceInfo.size() > 0 ) - return mDeviceInfo[ 0 ]; - - return NULL; -} diff --git a/Engine/source/sfx/sfxProvider.h b/Engine/source/sfx/sfxProvider.h index 34cbc832c..aa4209be9 100644 --- a/Engine/source/sfx/sfxProvider.h +++ b/Engine/source/sfx/sfxProvider.h @@ -23,102 +23,44 @@ #ifndef _SFXPROVIDER_H_ #define _SFXPROVIDER_H_ -#ifndef _TVECTOR_H_ - #include "core/util/tVector.h" +#ifndef _SFXCOMMON_H_ +#include "sfx/sfxCommon.h" #endif +#ifndef _TVECTOR_H_ +#include "core/util/tVector.h" +#endif + +#ifndef _UTIL_DELEGATE_H_ +#include "core/util/delegate.h" +#endif class SFXDevice; - - -struct SFXDeviceInfo +struct SFXProvider { - String driver; - String internalName; - String name; - bool hasHardware = false; - S32 maxBuffers =0; +public: + typedef Delegate CreateProviderInstanceDelegate; - virtual ~SFXDeviceInfo() {} -}; + String mName; + bool mHasHardware; + SFXProviderType mType; + SFXDeviceType mDeviceType; + U32 mIndex; + bool mDefault; + CreateProviderInstanceDelegate mCreateDeviceInstanceDelegate; -typedef Vector SFXDeviceInfoVector; - -class SFXProvider -{ - friend class SFXSystem; - - private: - - /// The head of the linked list of avalible providers. - static SFXProvider* smProviders; - - /// The next provider in the linked list of available providers. - SFXProvider* mNextProvider; - - /// The provider name which is passed by the concrete provider - /// class to the SFXProvider constructor. - String mName; - - static Vector sAllProviders; - - protected: - - /// The array of avaIlable devices from this provider. The - /// concrete provider class will fill this on construction. - SFXDeviceInfoVector mDeviceInfo; - - /// This registers the provider to the available provider list. It should be called - /// for providers that are properly initialized and available for device enumeration and creation. - /// the add and registration process is 2 steps to avoid issues when TGEA is used as a shared library (specifically on Windows) - static void regProvider( SFXProvider* provider ); - - virtual void init() = 0; - - SFXProvider( const String& name ); - ~SFXProvider(); - - /// Look up the SFXDeviceInfo for the given device in mDeviceInfo. - /// Return default device (first in list) if no other device matches (or null if device list is empty). - SFXDeviceInfo* _findDeviceInfo( const String& deviceName ); - - /// This is called from SFXSystem to create a new device. Must be implemented - /// by all contrete provider classes. - /// - /// @param deviceName The case sensitive name of the device or NULL to create the - // default device. - /// @param useHardware Toggles the use of hardware processing when available. - /// @param maxBuffers The maximum buffers for this device to use or -1 - /// for the device to pick a reasonable default for that device. - /// - /// @return Returns the created device or NULL for failure. - /// - virtual SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ) = 0; - - public: - - /// Returns a specific provider by searching the provider list - /// for the first provider with the case sensitive name. - static SFXProvider* findProvider( String providerName ); - - /// Returns the first provider in the provider list. Use - /// getNextProvider() to iterate over list. - static SFXProvider* getFirstProvider() { return smProviders; } - - /// Returns the next provider in the provider list or NULL - /// when the end of the list is reached. - SFXProvider* getNextProvider() const { return mNextProvider; } - - /// The case sensitive name of this provider. - const String& getName() const { return mName; } - - /// Returns a read only vector with device information for - /// all creatable devices available from this provider. - const SFXDeviceInfoVector& getDeviceInfo() const { return mDeviceInfo; } - - static void initializeAllProviders(); + const char* getName() const { return mName; } + SFXProvider() + { + mName = String::EmptyString; + mHasHardware = false; + mType = NullProvider; + mIndex = 0; + mDefault = false; + mDeviceType = Output; + } }; diff --git a/Engine/source/sfx/sfxSoundscape.cpp b/Engine/source/sfx/sfxSoundscape.cpp index b65c573d7..48b448e91 100644 --- a/Engine/source/sfx/sfxSoundscape.cpp +++ b/Engine/source/sfx/sfxSoundscape.cpp @@ -131,14 +131,30 @@ void SFXSoundscapeManager::update() SFXAmbience* ambience = mStack[ reverbIndex ]->getAmbience(); AssertFatal( ambience->getEnvironment(), "SFXSoundscapeManager::update - Reverb lookup return ambience without reverb!" ); - SFX->setRolloffFactor( ambience->getRolloffFactor() ); - SFX->setDopplerFactor( ambience->getDopplerFactor() ); - SFX->setReverb( ambience->getEnvironment()->getReverb() ); + SFX->setRolloffFactor(ambience->getRolloffFactor()); + SFX->setDopplerFactor(ambience->getDopplerFactor()); + SFX->setSpeedOfSound(ambience->getSpeedOfSound()); + if (ambience->getEnvironment()) + SFX->setReverb(ambience->getEnvironment()->getReverb()); } mCurrentReverbIndex = reverbIndex; } - + + if (mStack[mStack.size() - 1]->mDirtyBits.test(SFXSoundscape::AmbienceDirty)) + { + SFXAmbience* ambience = mStack[mStack.size() - 1]->getAmbience(); + SFX->setRolloffFactor(ambience->getRolloffFactor()); + SFX->setDopplerFactor(ambience->getDopplerFactor()); + SFX->setSpeedOfSound(ambience->getSpeedOfSound()); + if (ambience->getEnvironment()) + SFX->setReverb(ambience->getEnvironment()->getReverb()); + + mCurrentReverbIndex = mStack.size() - 1; + + mStack[mStack.size() - 1]->mDirtyBits.clear(SFXSoundscape::AmbienceDirty); + } + // Update the active soundscapes. for( U32 i = 0; i < mStack.size(); ++ i ) diff --git a/Engine/source/sfx/sfxSystem.cpp b/Engine/source/sfx/sfxSystem.cpp index 37133de0d..380173237 100644 --- a/Engine/source/sfx/sfxSystem.cpp +++ b/Engine/source/sfx/sfxSystem.cpp @@ -42,8 +42,11 @@ #include "platform/platformTimer.h" #include "core/util/autoPtr.h" #include "core/module.h" +#include "T3D/sfx/sfx3DWorld.h" +Vector SFXSystem::smProviders(__FILE__, __LINE__); +SFXSystem::RegisterProviderSignal* SFXSystem::smRegisterProviderSignal; MODULE_BEGIN( SFX ) @@ -54,6 +57,8 @@ MODULE_BEGIN( SFX ) MODULE_INIT { SFXSystem::init(); + if (engineAPI::gUseConsoleInterop) + SFXDevice::initConsole(); } MODULE_SHUTDOWN @@ -69,6 +74,25 @@ SFXSystem* SFXSystem::smSingleton = NULL; /// Default SFXAmbience used to reset the global soundscape. SFXAmbience *sDefaultAmbience; +// Provider type +ImplementEnumType(SFXProviderType, + "The sfx provider.\n" + "@ingroup SFX") +{ SFXProviderType::OpenAL, "OpenAL", "OpenAL Provider." }, +{ SFXProviderType::DirectSound, "DirectSound", "DirectSound Provider." }, +{ SFXProviderType::XAudio, "XAudio", "XAudio Provider." }, +{ SFXProviderType::NullProvider, "NullProvider","NullProvider Provider." } +EndImplementEnumType; + +// Device type +ImplementEnumType(SFXDeviceType, + "The sfx device type input/output.\n" + "@ingroup SFX") +{ SFXDeviceType::Input, "InputDevice", "Input/Capture device" }, +{ SFXDeviceType::Output, "OutputDevice", "Output Device." }, +EndImplementEnumType; + + // Excludes Null and Blocked as these are not passed out to the control layer. ImplementEnumType( SFXStatus, "Playback status of sound source.\n" @@ -185,6 +209,125 @@ static const U32 sDeviceInfoMaxBuffers = 3; //----------------------------------------------------------------------------- +SFXSystem::RegisterProviderSignal& SFXSystem::getRegisterProviderSignal() +{ + if (smRegisterProviderSignal) + return *smRegisterProviderSignal; + smRegisterProviderSignal = new RegisterProviderSignal(); + return *smRegisterProviderSignal; +} + +S32 SFXSystem::getProviderCount() +{ + return smProviders.size(); +} + +inline static void _SFXInitReportProviders(Vector& providers) +{ + for (U32 i = 0; i < providers.size(); i++) + { + switch (providers[i]->mType) + { + case OpenAL: + Con::printf(" OpenAL Device Found: %s Device %s %s", providers[i]->mDeviceType == Input ? "Input" : "Output", providers[i]->getName(), providers[i]->mDefault ? "(Default)" : ""); + break; + case NullProvider: + Con::printf(" Null device found"); + break; + case XAudio: + Con::printf(" XAudio Device Found: %s Device %s %s", providers[i]->mDeviceType == Input ? "Input" : "Output", providers[i]->getName(), providers[i]->mDefault ? "(Default)" : ""); + break; + case DirectSound: + Con::printf(" DirectSound Device Found: %s Device %s %s", providers[i]->mDeviceType == Input ? "Input" : "Output", providers[i]->getName(), providers[i]->mDefault ? "(Default)" : ""); + break; + default: + Con::printf(" Unknown device found"); + break; + } + } +} + +void SFXSystem::getProviders(Vector* providers) +{ + providers->clear(); + for (U32 k = 0; k < smProviders.size(); k++) + providers->push_back(smProviders[k]); +} + +const char* SFXSystem::getProviderNameFromType(SFXProviderType type) +{ + static const char* _names[] = { "OpenAL", "DirectSound", "XAudio", "NullProvider" }; + if (type < 0 || type >= SFXProviderType_Count) + return _names[OpenAL]; + + return _names[type]; +} + +SFXProvider* SFXSystem::getBestProviderChoice() +{ + const String provider = Con::getVariable("$pref::SFX::provider"); + const String device = Con::getVariable("$pref::SFX::device"); + + SFXProviderType providerType = OpenAL; + + if (provider.isEmpty() || device.isEmpty()) + { + for (U32 i = 0; i < smProviders.size(); i++) + { + if (smProviders[i]->mType == OpenAL) + { + if (smProviders[i]->mDefault) + return smProviders[i]; + } + } + } + else + { + S32 ret = -1; + for (U32 i = 0; i < SFXProviderType_Count; i++) + { + if (!dStrcmp(getProviderNameFromType((SFXProviderType)i), provider)) + { + ret = i; + break; + } + } + + if (ret == -1) + providerType = OpenAL; + } + + U32 i = 0; + for (i = 0; i < smProviders.size(); i++) + { + if (smProviders[i]->mType == providerType) + { + if (String::compare(smProviders[i]->getName(), device.c_str()) == 0) + { + return smProviders[i]; + } + } + } + + for (i = 0; i < smProviders.size(); i++) + { + if (smProviders[i]->mType == providerType) + { + if (smProviders[i]->mDefault) + return smProviders[i]; + } + } + + + + return NULL; +} + +SFXProvider* SFXSystem::getProvider(U32 index) +{ + return smProviders[index]; +} + SFXSystem::SFXSystem() : mDevice( NULL ), mLastSourceUpdateTime( 0 ), @@ -200,6 +343,7 @@ SFXSystem::SFXSystem() mDistanceModel( SFXDistanceModelLinear ), mStatAmbientUpdateTime( 0 ), mDopplerFactor( 0.5 ), + mSpeedOfSound(343.3f), mRolloffFactor( 1.0 ), mSoundscapeMgr( NULL ) { @@ -340,15 +484,36 @@ SFXSystem::~SFXSystem() deleteDevice(); } +void SFXSystem::enumerateProviders() +{ + if (smProviders.size()) + { + return; + } + + getRegisterProviderSignal().trigger(SFXSystem::smProviders); +} + //----------------------------------------------------------------------------- void SFXSystem::init() { AssertWarn( smSingleton == NULL, "SFX has already been initialized!" ); - SFXProvider::initializeAllProviders(); - - // Create the stream thread pool. + // SFXProvider::initializeAllProviders(); + Con::printf("SFX Init:"); + + // find our providers + Vector providers( __FILE__, __LINE__ ); + SFXSystem::enumerateProviders(); + SFXSystem::getProviders(&providers); + + if (!providers.size()) + Con::errorf("Could not find a sound provider"); + + //loop through and tell the user what kind of provider we found + _SFXInitReportProviders(providers); + Con::printf(""); SFXInternal::SFXThreadPool::createSingleton(); @@ -366,6 +531,13 @@ void SFXSystem::destroy() { AssertWarn( smSingleton != NULL, "SFX has not been initialized!" ); + while (smProviders.size()) + { + SFXProvider* provider = smProviders.last(); + smProviders.decrement(); + delete provider; + } + delete smSingleton; smSingleton = NULL; @@ -373,6 +545,9 @@ void SFXSystem::destroy() SFXInternal::SFXThreadPool::deleteSingleton(); delete(sDefaultAmbience); + + if (smRegisterProviderSignal) + SAFE_DELETE(smRegisterProviderSignal); } //----------------------------------------------------------------------------- @@ -399,59 +574,46 @@ void SFXSystem::removePlugin( SFXSystemPlugin* plugin ) //----------------------------------------------------------------------------- -bool SFXSystem::createDevice( const String& providerName, const String& deviceName, bool useHardware, S32 maxBuffers, bool changeDevice ) +bool SFXSystem::createDevice(SFXProvider* provider) { - // Make sure we don't have a device already. - - if( mDevice && !changeDevice ) - return false; - - // Lookup the provider. - - SFXProvider* provider = SFXProvider::findProvider( providerName ); - if( !provider ) - return false; - - // If we have already created this device and are using it then no need to do anything. - - if( mDevice - && providerName.equal( mDevice->getProvider()->getName(), String::NoCase ) - && deviceName.equal( mDevice->getName(), String::NoCase ) - && useHardware == mDevice->getUseHardware() ) - return true; - - // If we have an existing device remove it. - - if( mDevice ) + // this should probably just happen tbh. + if (mDevice) deleteDevice(); - // Create the new device.. - - mDevice = provider->createDevice( deviceName, useHardware, maxBuffers ); + mDevice = provider->mCreateDeviceInstanceDelegate(provider->mIndex); if( !mDevice ) { - Con::errorf( "SFXSystem::createDevice - failed creating %s device '%s'", providerName.c_str(), deviceName.c_str() ); + Con::errorf( "SFXSystem::createDevice - failed creating device '%s'", provider->getName()); return false; } - - // Print capabilities. + mDevice->setProvider(*provider); - Con::printf( "SFXSystem::createDevice - created %s device '%s'", providerName.c_str(), deviceName.c_str() ); - if( mDevice->getCaps() & SFXDevice::CAPS_Reverb ) - Con::printf( " CAPS_Reverb" ); - if( mDevice->getCaps() & SFXDevice::CAPS_VoiceManagement ) - Con::printf( " CAPS_VoiceManagement" ); - if( mDevice->getCaps() & SFXDevice::CAPS_Occlusion ) - Con::printf( "\tCAPS_Occlusion" ); - if( mDevice->getCaps() & SFXDevice::CAPS_MultiListener ) - Con::printf( "\tCAPS_MultiListener" ); + // Print capabilities. + Con::printf( "\nSFXSystem::createDevice - created device '%s'", provider->getName()); + Con::printf("| Device Update Interval: %d ms", SFXDevice::smUpdateInterval); + Con::printf("| Device Sample rate: %d Hz", SFXDevice::smDeviceFrequency); + Con::printf("| Device Bitrate: %d", SFXDevice::smDeviceBitrate); + if (mDevice->getCaps() & SFXDevice::CAPS_Reverb) + Con::printf("| CAPS_Reverb"); + if (mDevice->getCaps() & SFXDevice::CAPS_VoiceManagement) + Con::printf("| CAPS_VoiceManagement"); + if (mDevice->getCaps() & SFXDevice::CAPS_Occlusion) + Con::printf("| CAPS_Occlusion"); + if (mDevice->getCaps() & SFXDevice::CAPS_MultiListener) + Con::printf("| CAPS_MultiListener"); + if (mDevice->getCaps() & SFXDevice::CAPS_HRTF) + Con::printf("| CAPS_HRTF"); + if (mDevice->getCaps() & SFXDevice::CAPS_Float32) + Con::printf("| CAPS_Float32"); + if (mDevice->getCaps() & SFXDevice::CAPS_MonoStereo) + Con::printf("| CAPS_MonoStereo"); // Set defaults. - mDevice->setNumListeners( getNumListeners() ); mDevice->setDistanceModel( mDistanceModel ); mDevice->setDopplerFactor( mDopplerFactor ); mDevice->setRolloffFactor( mRolloffFactor ); + mDevice->setSpeedOfSound(mSpeedOfSound); //OpenAL requires slots for effects, this creates an empty function //that will run when a sfxdevice is created. mDevice->openSlots(); @@ -464,17 +626,15 @@ bool SFXSystem::createDevice( const String& providerName, const String& deviceNa return true; } -//----------------------------------------------------------------------------- - String SFXSystem::getDeviceInfoString() { // Make sure we have a valid device. if( !mDevice ) return String(); - return String::ToString( "%s\t%s\t%s\t%d\t%d", - mDevice->getProvider()->getName().c_str(), - mDevice->getName().c_str(), + return String::ToString( "%s\t%s\t%s\t%d\t%d", + getProviderNameFromType(mDevice->getProvider().mType), + mDevice->getProvider().getName(), mDevice->getUseHardware() ? "1" : "0", mDevice->getMaxBuffers(), mDevice->getCaps() ); @@ -1020,6 +1180,18 @@ void SFXSystem::setDopplerFactor( F32 factor ) //----------------------------------------------------------------------------- + +void SFXSystem::setSpeedOfSound(F32 speedOfSound) +{ + const bool changed = (speedOfSound != mSpeedOfSound); + + mSpeedOfSound = speedOfSound; + if (mDevice && changed) + mDevice->setSpeedOfSound(speedOfSound); +} + +//----------------------------------------------------------------------------- + void SFXSystem::setRolloffFactor( F32 factor ) { const bool changed = ( factor != mRolloffFactor ); @@ -1210,6 +1382,43 @@ void SFXSystem::dumpSources( StringBuilder* toString, bool excludeGroups ) //----------------------------------------------------------------------------- +DefineEngineFunction(sfxGetProviderCount, S32, (), , + "Returns the number of sound providers available\n\n" + "@ingroup SFX") +{ + return SFXSystem::getProviderCount(); +} + +DefineEngineFunction(sfxGetProviderType, SFXProviderType, (S32 index), , + "Returns the type (OpenAL, XAudio, DirectSound, Null) of a sound provider.\n" + "@param index The index of the adapter.") +{ + Vector providers(__FILE__, __LINE__); + SFXSystem::getProviders(&providers); + + if (index >= 0 && index < providers.size()) + return providers[index]->mType; + + Con::errorf("SFXSystem::sfxGetProviderType - Out of range provider index."); + return SFXProviderType_Count; +} + +DefineEngineFunction(sfxGetProviderDevice, const char*, (S32 index), , + "Returns the device name of the sound provider.\n" + "@param index The index of the adapter.") +{ + Vector providers(__FILE__, __LINE__); + SFXSystem::getProviders(&providers); + + if (index >= 0 && index < providers.size()) + return providers[index]->getName(); + + Con::errorf("SFXSystem::sfxGetProviderDevice - Out of range provider index."); + return ""; +} + + + DefineEngineFunction( sfxGetAvailableDevices, const char*, (),, "Get a list of all available sound devices.\n" "The return value will be a newline-separated list of entries where each line describes one available sound " @@ -1240,27 +1449,14 @@ DefineEngineFunction( sfxGetAvailableDevices, const char*, (),, char *ptr = deviceList; *ptr = 0; - SFXProvider* provider = SFXProvider::getFirstProvider(); - while ( provider ) + Vector providers(__FILE__, __LINE__); + SFXSystem::getProviders(&providers); + + for (U32 i = 0; i < providers.size(); i++) { - // List the devices in this provider. - const SFXDeviceInfoVector& deviceInfo = provider->getDeviceInfo(); - for ( S32 d=0; d < deviceInfo.size(); d++ ) - { - const SFXDeviceInfo* info = deviceInfo[d]; - const char *providerName = provider->getName().c_str(); - char *infoName = (char*)info->name.c_str(); - - dSprintf(ptr, len, "%s\t%s\t%s\t%i\n", providerName, infoName, info->hasHardware ? "1" : "0", info->maxBuffers); - - ptr += dStrlen(ptr); - len = bufferSize - (ptr - deviceList); - - if (len <= 0) - return deviceList; - } - - provider = provider->getNextProvider(); + dSprintf(ptr, len, "%s\t", providers[i]->getName()); + ptr += dStrlen(ptr); + len = bufferSize - (ptr - deviceList); } return deviceList; @@ -1268,7 +1464,7 @@ DefineEngineFunction( sfxGetAvailableDevices, const char*, (),, //----------------------------------------------------------------------------- -DefineEngineFunction( sfxCreateDevice, bool, ( const char* provider, const char* device, bool useHardware, S32 maxBuffers ),, +DefineEngineFunction( sfxCreateDevice, bool, (),, "Try to create a new sound device using the given properties.\n" "If a sound device is currently initialized, it will be uninitialized first. However, be aware that in this case, " "if this function fails, it will not restore the previously active device but rather leave the sound system in an " @@ -1276,10 +1472,6 @@ DefineEngineFunction( sfxCreateDevice, bool, ( const char* provider, const char* "Sounds that are already playing while the new device is created will be temporarily transitioned to virtualized " "playback and then resume normal playback once the device has been created.\n\n" "In the core scripts, sound is automatically set up during startup in the sfxStartup() function.\n\n" - "@param provider The name of the device provider as returned by sfxGetAvailableDevices().\n" - "@param device The name of the device as returned by sfxGetAvailableDevices().\n" - "@param useHardware Whether to enabled hardware mixing on the device or not. Only relevant if supported by the given device.\n" - "@param maxBuffers The maximum number of concurrent voices for this device to use or -1 for the device to pick its own reasonable default." "@return True if the initialization was successful, false if not.\n" "@note This function must be called before any of the sound playback functions can be used.\n" "@see sfxGetAvailableDevices\n" @@ -1288,7 +1480,14 @@ DefineEngineFunction( sfxCreateDevice, bool, ( const char* provider, const char* "@ref SFX_devices\n" "@ingroup SFX" ) { - return SFX->createDevice( provider, device, useHardware, maxBuffers, true ); + // return SFX->createDevice( provider, device, useHardware, maxBuffers, true ); + SFXProvider* p = SFXSystem::getBestProviderChoice(); + if (p) + { + SFX->createDevice(p); + return true; + } + return false; } //----------------------------------------------------------------------------- diff --git a/Engine/source/sfx/sfxSystem.h b/Engine/source/sfx/sfxSystem.h index 7ac0b6f24..b1157574e 100644 --- a/Engine/source/sfx/sfxSystem.h +++ b/Engine/source/sfx/sfxSystem.h @@ -23,9 +23,10 @@ #ifndef _SFXSYSTEM_H_ #define _SFXSYSTEM_H_ -#ifndef _SFXCOMMON_H_ - #include "sfx/sfxCommon.h" -#endif +#ifndef _SFXPROVIDER_H_ +#include "sfx/sfxProvider.h" +#endif // !_SFXPROVIDER_H_ + #ifndef _TSIGNAL_H_ #include "core/util/tSignal.h" #endif @@ -98,343 +99,358 @@ class SFXSystemPlugin /// class SFXSystem { - friend class SFXSound; // _assignVoices - friend class SFXSource; // _onAddSource, _onRemoveSource. - friend class SFXProfile; // _createBuffer. + friend class SFXSound; // _assignVoices + friend class SFXSource; // _onAddSource, _onRemoveSource. + friend class SFXProfile; // _createBuffer. + +public: + /// Allows device to register themselves as available + typedef Signal&)> RegisterProviderSignal; + static RegisterProviderSignal& getRegisterProviderSignal(); + /// Get the number of available providers. + static S32 getProviderCount(); + /// Enumerate all the sound providers on the system + static void enumerateProviders(); + static void getProviders(Vector* providers); + static const char* getProviderNameFromType(SFXProviderType type); + static SFXProvider* getBestProviderChoice(); + static SFXProvider* getProvider(U32 index); + + typedef Signal< void( SFXSystemEventType event ) > EventSignalType; + typedef Vector< SFXSource* > SFXSourceVector; + typedef Vector< SFXSound* > SFXSoundVector; +private: + /// List of known adapters. + static Vector smProviders; + static RegisterProviderSignal* smRegisterProviderSignal; + +protected: + + /// The one and only instance of the SFXSystem. + static SFXSystem* smSingleton; + + /// The protected constructor. + /// + /// @see SFXSystem::init() + /// + SFXSystem(); + + /// The non-virtual destructor. You shouldn't + /// ever need to overload this class. + ~SFXSystem(); - public: - typedef Signal< void( SFXSystemEventType event ) > EventSignalType; - typedef Vector< SFXSource* > SFXSourceVector; - typedef Vector< SFXSound* > SFXSoundVector; + /// The current output sound device initialized + /// and ready to play back. + SFXDevice* mDevice; - protected: + /// + SFXSoundVector mSounds; - /// The one and only instance of the SFXSystem. - static SFXSystem* smSingleton; - - /// The protected constructor. - /// - /// @see SFXSystem::init() - /// - SFXSystem(); - - /// The non-virtual destructor. You shouldn't - /// ever need to overload this class. - ~SFXSystem(); - - /// The current output sound device initialized - /// and ready to play back. - SFXDevice* mDevice; - - /// - SFXSoundVector mSounds; - - /// This is used to keep track of play once sources - /// that must be released when they stop playing. - SFXSourceVector mPlayOnceSources; + /// This is used to keep track of play once sources + /// that must be released when they stop playing. + SFXSourceVector mPlayOnceSources; - /// The last time the sources got an update. - U32 mLastSourceUpdateTime; + /// The last time the sources got an update. + U32 mLastSourceUpdateTime; - /// - U32 mLastAmbientUpdateTime; + /// + U32 mLastAmbientUpdateTime; - /// - U32 mLastParameterUpdateTime; + /// + U32 mLastParameterUpdateTime; - /// The distance model used for rolloff curve computation on 3D sounds. - SFXDistanceModel mDistanceModel; + /// The distance model used for rolloff curve computation on 3D sounds. + SFXDistanceModel mDistanceModel; - /// The current doppler scale factor. - F32 mDopplerFactor; + /// The current doppler scale factor. + F32 mDopplerFactor; + + /// The current speed of sound. + F32 mSpeedOfSound; - /// The current curve rolloff factor. - F32 mRolloffFactor; + /// The current curve rolloff factor. + F32 mRolloffFactor; - /// The current position and orientation of all listeners. - Vector< SFXListenerProperties > mListeners; + /// The current position and orientation of all listeners. + Vector< SFXListenerProperties > mListeners; - /// Current global reverb properties. - SFXReverbProperties mReverb; + /// Current global reverb properties. + SFXReverbProperties mReverb; - /// SFX system event signal. - EventSignalType mEventSignal; + /// SFX system event signal. + EventSignalType mEventSignal; - /// Ambient soundscape manager. - SFXSoundscapeManager* mSoundscapeMgr; + /// Ambient soundscape manager. + SFXSoundscapeManager* mSoundscapeMgr; - /// List of plugins currently linked to the SFX system. - Vector< SFXSystemPlugin* > mPlugins; + /// List of plugins currently linked to the SFX system. + Vector< SFXSystemPlugin* > mPlugins; - /// @name Stats - /// - /// Stats reported back to the console for tracking performance. - /// - /// @{ + /// @name Stats + /// + /// Stats reported back to the console for tracking performance. + /// + /// @{ - S32 mStatNumSources; - S32 mStatNumSounds; - S32 mStatNumPlaying; - S32 mStatNumCulled; - S32 mStatNumVoices; - S32 mStatSourceUpdateTime; - S32 mStatParameterUpdateTime; - S32 mStatAmbientUpdateTime; + S32 mStatNumSources; + S32 mStatNumSounds; + S32 mStatNumPlaying; + S32 mStatNumCulled; + S32 mStatNumVoices; + S32 mStatSourceUpdateTime; + S32 mStatParameterUpdateTime; + S32 mStatAmbientUpdateTime; - /// @} + /// @} - /// Called to reprioritize and reassign buffers as - /// sources change state, volumes are adjusted, and - /// the listener moves around. - /// - /// @see SFXSource::_update() - /// - void _updateSources(); + /// Called to reprioritize and reassign buffers as + /// sources change state, volumes are adjusted, and + /// the listener moves around. + /// + /// @see SFXSource::_update() + /// + void _updateSources(); - /// This called to reprioritize and reassign - /// voices to sources. - void _assignVoices(); + /// This called to reprioritize and reassign + /// voices to sources. + void _assignVoices(); - /// - void _assignVoice( SFXSound* sound ); + /// + void _assignVoice( SFXSound* sound ); - /// - void _sortSounds( const SFXListenerProperties& listener ); + /// + void _sortSounds( const SFXListenerProperties& listener ); - /// Called from SFXSource::onAdd to register the source. - void _onAddSource( SFXSource* source ); + /// Called from SFXSource::onAdd to register the source. + void _onAddSource( SFXSource* source ); - /// Called from SFXSource::onRemove to unregister the source. - void _onRemoveSource( SFXSource* source ); + /// Called from SFXSource::onRemove to unregister the source. + void _onRemoveSource( SFXSource* source ); - /// Called from SFXProfile to create a device specific - /// sound buffer used in conjunction with a voice in playback. - SFXBuffer* _createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ); + /// Called from SFXProfile to create a device specific + /// sound buffer used in conjunction with a voice in playback. + SFXBuffer* _createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ); - /// Load file directly through SFXDevice. Depends on - /// availability with selected SFXDevice. - /// - /// @return Return new buffer or NULL. - SFXBuffer* _createBuffer( const String& filename, SFXDescription* description ); + /// Load file directly through SFXDevice. Depends on + /// availability with selected SFXDevice. + /// + /// @return Return new buffer or NULL. + SFXBuffer* _createBuffer( const String& filename, SFXDescription* description ); - /// - SFXDevice* _getDevice() const { return mDevice; } + /// + SFXDevice* _getDevice() const { return mDevice; } - public: +public: - /// Returns the one an only instance of the SFXSystem - /// unless it hasn't been initialized or its been disabled - /// in your build. - /// - /// For convienence you can use the SFX-> macro as well. - /// - /// @see SFXSystem::init() - /// @see SFX - static SFXSystem* getSingleton() { return smSingleton; } + /// Returns the one an only instance of the SFXSystem + /// unless it hasn't been initialized or its been disabled + /// in your build. + /// + /// For convienence you can use the SFX-> macro as well. + /// + /// @see SFXSystem::init() + /// @see SFX + static SFXSystem* getSingleton() { return smSingleton; } - /// This is called from initialization to prepare the - /// sound system singleton. This also includes registering - /// common resource types and initializing available sound - /// providers. - static void init(); + /// This is called from initialization to prepare the + /// sound system singleton. This also includes registering + /// common resource types and initializing available sound + /// providers. + static void init(); - /// This is called after Sim::shutdown() in shutdownLibraries() - /// to free the sound system singlton. After this the SFX - /// singleton is null and any call to it will crash. - static void destroy(); + /// This is called after Sim::shutdown() in shutdownLibraries() + /// to free the sound system singlton. After this the SFX + /// singleton is null and any call to it will crash. + static void destroy(); - /// This is only public so that it can be called by - /// the game update loop. It updates the current - /// device and all sources. - void _update(); + /// This is only public so that it can be called by + /// the game update loop. It updates the current + /// device and all sources. + void _update(); - /// Register the given plugin with the system. - void addPlugin( SFXSystemPlugin* plugin ); + /// Register the given plugin with the system. + void addPlugin( SFXSystemPlugin* plugin ); - /// Unregister the given plugin with the system. - void removePlugin( SFXSystemPlugin* plugin ); + /// Unregister the given plugin with the system. + void removePlugin( SFXSystemPlugin* plugin ); - /// @name Device Management - /// @{ + /// @name Device Management + /// @{ - /// This initializes a new device. - /// - /// @param providerName The name of the provider. - /// @param deviceName The name of the provider device. - /// @param useHardware Toggles the use of hardware processing when available. - /// @param maxBuffers The maximum buffers for this device to use or -1 - /// for the device to pick its own reasonable default. - /// @param changeDevice Allows this to change the current device to a new one - /// @return Returns true if the device was created. - bool createDevice( const String& providerName, - const String& deviceName, - bool useHardware, - S32 maxBuffers, - bool changeDevice = false); + /// This initializes a new device. + /// + /// @return Returns true if the device was created. + bool createDevice( SFXProvider* provider); - /// Returns the current device information or NULL if no - /// device is present. The information string is in the - /// following format: - /// - /// Provider Name\tDevice Name\tUse Hardware\tMax Buffers - String getDeviceInfoString(); + /// Returns the current device information or NULL if no + /// device is present. The information string is in the + /// following format: + /// + /// Provider Name\tDevice Name\tUse Hardware\tMax Buffers + String getDeviceInfoString(); - /// This destroys the current device. All sources loose their - /// playback buffers, but otherwise continue to function. - void deleteDevice(); + /// This destroys the current device. All sources loose their + /// playback buffers, but otherwise continue to function. + void deleteDevice(); - /// Returns true if a device is allocated. - bool hasDevice() const { return mDevice != NULL; } + /// Returns true if a device is allocated. + bool hasDevice() const { return mDevice != NULL; } - /// @} + /// @} - /// @name Source Creation - /// @{ + /// @name Source Creation + /// @{ - /// Used to create new sound sources from a sound profile. The - /// returned source is in a stopped state and ready for playback. - /// Use the SFX_DELETE macro to free the source when your done. - /// - /// @note The track must have at least the same lifetime as the - /// source. If the description disappears while the source is still - /// there, the source will go with it. - /// - /// @param profile The sound profile for the created source. - /// @param transform The optional transform if creating a 3D source. - /// @param velocity The optional doppler velocity if creating a 3D source. - /// - /// @return The sound source or NULL if an error occured. - SFXSource* createSource( SFXTrack* track, - const MatrixF* transform = NULL, - const VectorF* velocity = NULL ); + /// Used to create new sound sources from a sound profile. The + /// returned source is in a stopped state and ready for playback. + /// Use the SFX_DELETE macro to free the source when your done. + /// + /// @note The track must have at least the same lifetime as the + /// source. If the description disappears while the source is still + /// there, the source will go with it. + /// + /// @param profile The sound profile for the created source. + /// @param transform The optional transform if creating a 3D source. + /// @param velocity The optional doppler velocity if creating a 3D source. + /// + /// @return The sound source or NULL if an error occured. + SFXSource* createSource( SFXTrack* track, + const MatrixF* transform = NULL, + const VectorF* velocity = NULL ); - /// Used to create a streaming sound source from a user supplied - /// stream object. - /// - /// It is only intended for memory based streams. For sound file - /// streaming use createSource() with a streaming SFXProfile. - /// - /// Use the SFX_DELETE macro to free the source when your done. - /// - /// @note The description must have at least the same lifetime as the - /// sound. If the description disappears while the source is still - /// there, the sound will go with it. - /// - /// @param stream The stream used to create the sound buffer. It - /// must exist for the lifetime of the source and will - /// have its reference count decremented when the source - /// is destroyed. - /// - /// @param description The sound description to apply to the source. - /// - /// @return The sound source or NULL if an error occured. - SFXSound* createSourceFromStream( const ThreadSafeRef< SFXStream >& stream, - SFXDescription* description ); + /// Used to create a streaming sound source from a user supplied + /// stream object. + /// + /// It is only intended for memory based streams. For sound file + /// streaming use createSource() with a streaming SFXProfile. + /// + /// Use the SFX_DELETE macro to free the source when your done. + /// + /// @note The description must have at least the same lifetime as the + /// sound. If the description disappears while the source is still + /// there, the sound will go with it. + /// + /// @param stream The stream used to create the sound buffer. It + /// must exist for the lifetime of the source and will + /// have its reference count decremented when the source + /// is destroyed. + /// + /// @param description The sound description to apply to the source. + /// + /// @return The sound source or NULL if an error occured. + SFXSound* createSourceFromStream( const ThreadSafeRef< SFXStream >& stream, + SFXDescription* description ); - /// Creates a source which when it finishes playing will auto delete - /// itself. Be aware that the returned SFXSource pointer should only - /// be used for error checking or immediate setting changes. It may - /// be deleted as soon as the next system tick. - /// - /// @param profile The sound profile for the created source. - /// @param transform The optional transform if creating a 3D source. - /// @param velocity The optional doppler velocity if creating a 3D source. - /// - /// @return The sound source or NULL if an error occured. - SFXSource* playOnce( SFXTrack* track, - const MatrixF* transform = NULL, - const VectorF* velocity = NULL, - F32 fadeInTime = -1.f ); - SFXSource* playOnce( SFXProfile* profile, - const MatrixF* transform = NULL, - const VectorF* velocity = NULL, - F32 fadeInTime = -1.f ) - { // Avoids having to require inclusion of sfxProfile.h - return playOnce( ( SFXTrack* ) profile, transform, velocity, fadeInTime ); - } + /// Creates a source which when it finishes playing will auto delete + /// itself. Be aware that the returned SFXSource pointer should only + /// be used for error checking or immediate setting changes. It may + /// be deleted as soon as the next system tick. + /// + /// @param profile The sound profile for the created source. + /// @param transform The optional transform if creating a 3D source. + /// @param velocity The optional doppler velocity if creating a 3D source. + /// + /// @return The sound source or NULL if an error occured. + SFXSource* playOnce( SFXTrack* track, + const MatrixF* transform = NULL, + const VectorF* velocity = NULL, + F32 fadeInTime = -1.f ); + SFXSource* playOnce( SFXProfile* profile, + const MatrixF* transform = NULL, + const VectorF* velocity = NULL, + F32 fadeInTime = -1.f ) + { // Avoids having to require inclusion of sfxProfile.h + return playOnce( ( SFXTrack* ) profile, transform, velocity, fadeInTime ); + } - /// Stop the source and delete it. This method will take care of - /// the fade-out time that the source may need before it will actually - /// stop and may be deleted. - void stopAndDeleteSource( SFXSource* source ); + /// Stop the source and delete it. This method will take care of + /// the fade-out time that the source may need before it will actually + /// stop and may be deleted. + void stopAndDeleteSource( SFXSource* source ); - /// Mark source for deletion when it is moving into stopped state. - /// This method is useful to basically make a source a play-once source - /// after the fact. - void deleteWhenStopped( SFXSource* source ); + /// Mark source for deletion when it is moving into stopped state. + /// This method is useful to basically make a source a play-once source + /// after the fact. + void deleteWhenStopped( SFXSource* source ); - /// @} + /// @} - /// @} + /// @} - /// @name Listeners - /// @{ + /// @name Listeners + /// @{ - /// Return the number of listeners currently configured. - U32 getNumListeners() const { return mListeners.size(); } + /// Return the number of listeners currently configured. + U32 getNumListeners() const { return mListeners.size(); } - /// Set the number of concurrent listeners. - /// @note It depends on the selected device if more than one listener is actually supported. - void setNumListeners( U32 num ); + /// Set the number of concurrent listeners. + /// @note It depends on the selected device if more than one listener is actually supported. + void setNumListeners( U32 num ); - /// Set the property of the given listener. - const SFXListenerProperties& getListener( U32 index = 0 ) const { return mListeners[ index ]; } + /// Set the property of the given listener. + const SFXListenerProperties& getListener( U32 index = 0 ) const { return mListeners[ index ]; } - /// Set the 3D attributes of the given listener. - void setListener( U32 index, const MatrixF& transform, const Point3F& velocity ); - void setListener( U32 index, const SFXListenerProperties& properties ) - { - setListener( index, properties.getTransform(), properties.getVelocity() ); - } + /// Set the 3D attributes of the given listener. + void setListener( U32 index, const MatrixF& transform, const Point3F& velocity ); + void setListener( U32 index, const SFXListenerProperties& properties ) + { + setListener( index, properties.getTransform(), properties.getVelocity() ); + } - /// @} + /// @} - /// @name 3D Sound Configuration - /// { + /// @name 3D Sound Configuration + /// { - /// Return the curve model currently used distance attenuation of positional sounds. - SFXDistanceModel getDistanceModel() const { return mDistanceModel; } + /// Return the curve model currently used distance attenuation of positional sounds. + SFXDistanceModel getDistanceModel() const { return mDistanceModel; } - /// - void setDistanceModel( SFXDistanceModel model ); + /// + void setDistanceModel( SFXDistanceModel model ); - /// - F32 getDopplerFactor() const { return mDopplerFactor; } + /// + F32 getDopplerFactor() const { return mDopplerFactor; } - /// - void setDopplerFactor( F32 factor ); + /// + void setDopplerFactor( F32 factor ); - /// - F32 getRolloffFactor() const { return mRolloffFactor; } + /// + F32 getRolloffFactor() const { return mRolloffFactor; } + + /// + /// Change the devices speed of sound. + /// + /// F32 for speed of sound. + void setSpeedOfSound(F32 speedOfSound); + + /// + void setRolloffFactor( F32 factor ); - /// - void setRolloffFactor( F32 factor ); + /// + const SFXReverbProperties& getReverb() const { return mReverb; } - /// - const SFXReverbProperties& getReverb() const { return mReverb; } + /// + void setReverb( const SFXReverbProperties& reverb ); - /// - void setReverb( const SFXReverbProperties& reverb ); + /// @} - /// @} + /// + SFXSoundscapeManager* getSoundscapeManager() const { return mSoundscapeMgr; } - /// - SFXSoundscapeManager* getSoundscapeManager() const { return mSoundscapeMgr; } + /// Dump information about all current SFXSources to the console or + /// to the given StringBuilder. + void dumpSources( StringBuilder* toString = NULL, bool excludeGroups = true ); - /// Dump information about all current SFXSources to the console or - /// to the given StringBuilder. - void dumpSources( StringBuilder* toString = NULL, bool excludeGroups = true ); + /// Return the SFX system event signal. + EventSignalType& getEventSignal() { return mEventSignal; } - /// Return the SFX system event signal. - EventSignalType& getEventSignal() { return mEventSignal; } + /// Notify the SFX system that the given description has changed. + /// All sources currently using the description will be updated. + void notifyDescriptionChanged( SFXDescription* description); - /// Notify the SFX system that the given description has changed. - /// All sources currently using the description will be updated. - void notifyDescriptionChanged( SFXDescription* description); - - /// - void notifyTrackChanged( SFXTrack* track ); + /// + void notifyTrackChanged( SFXTrack* track ); }; diff --git a/Engine/source/sfx/sfxWorld.h b/Engine/source/sfx/sfxWorld.h index 288644ace..5442545be 100644 --- a/Engine/source/sfx/sfxWorld.h +++ b/Engine/source/sfx/sfxWorld.h @@ -387,7 +387,7 @@ void SFXWorld< NUM_DIMENSIONS, Object >::_onScopeOut( Object object ) // Remove its soundscape. Scope& scope = mScopeStack[ index ]; - if( scope.mSoundscape ) + if( scope.mSoundscape && SFX ) SFX->getSoundscapeManager()->removeSoundscape( scope.mSoundscape ); mScopeStack.erase( index ); diff --git a/Engine/source/sfx/xaudio/sfxXAudioBuffer.cpp b/Engine/source/sfx/xaudio/sfxXAudioBuffer.cpp deleted file mode 100644 index 166815ee7..000000000 --- a/Engine/source/sfx/xaudio/sfxXAudioBuffer.cpp +++ /dev/null @@ -1,125 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "sfx/xaudio/sfxXAudioBuffer.h" -#include "sfx/xaudio/sfxXAudioVoice.h" - - -//#define DEBUG_SPEW - - -SFXXAudioBuffer* SFXXAudioBuffer::create( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ) -{ - SFXXAudioBuffer *buffer = new SFXXAudioBuffer( stream, description ); - return buffer; -} - -SFXXAudioBuffer::SFXXAudioBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ) - : Parent( stream, description ) -{ - VECTOR_SET_ASSOCIATION( mBufferQueue ); -} - -SFXXAudioBuffer::~SFXXAudioBuffer() -{ - _flush(); -} - -void SFXXAudioBuffer::write( SFXInternal::SFXStreamPacket* const* packets, U32 num ) -{ - AssertFatal( SFXInternal::isSFXThread(), "SFXXAudioBuffer::write() - not on SFX thread" ); - - using namespace SFXInternal; - - // Unqueue processed packets. - - if( isStreaming() ) - { - EnterCriticalSection( &_getUniqueVoice()->mLock ); - - XAUDIO2_VOICE_STATE state; - _getUniqueVoice()->mXAudioVoice->GetState( &state ); - - U32 numProcessed = mBufferQueue.size() - state.BuffersQueued; - for( U32 i = 0; i < numProcessed; ++ i ) - { - destructSingle< SFXStreamPacket* >( mBufferQueue.first().mPacket ); - mBufferQueue.pop_front(); - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioBuffer] Unqueued packet" ); - #endif - } - - LeaveCriticalSection( &_getUniqueVoice()->mLock ); - } - - // Queue new packets. - - for( U32 i = 0; i < num; ++ i ) - { - SFXStreamPacket* packet = packets[ i ]; - Buffer buffer; - - if( packet->mIsLast ) - buffer.mData.Flags = XAUDIO2_END_OF_STREAM; - - buffer.mPacket = packet; - buffer.mData.AudioBytes = packet->mSizeActual; - buffer.mData.pAudioData = packet->data; - - mBufferQueue.push_back( buffer ); - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioBuffer] Queued packet" ); - #endif - - // If this is a streaming buffer, submit the packet to the - // voice queue right away. - - if( isStreaming() ) - { - EnterCriticalSection( &_getUniqueVoice()->mLock ); - - IXAudio2SourceVoice* voice = _getUniqueVoice()->mXAudioVoice; - voice->SubmitSourceBuffer( &buffer.mData ); - - LeaveCriticalSection( &_getUniqueVoice()->mLock ); - } - } -} - -void SFXXAudioBuffer::_flush() -{ - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioBuffer] Flushing buffer" ); - #endif - - if( _getUniqueVoice() ) - _getUniqueVoice()->_stop(); - - while( !mBufferQueue.empty() ) - { - destructSingle( mBufferQueue.last().mPacket ); - mBufferQueue.pop_back(); - } -} diff --git a/Engine/source/sfx/xaudio/sfxXAudioBuffer.h b/Engine/source/sfx/xaudio/sfxXAudioBuffer.h deleted file mode 100644 index a1bcee139..000000000 --- a/Engine/source/sfx/xaudio/sfxXAudioBuffer.h +++ /dev/null @@ -1,83 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _SFXXAUDIOBUFFER_H_ -#define _SFXXAUDIOBUFFER_H_ - -#include - -#ifndef _SFXINTERNAL_H_ -#include "sfx/sfxInternal.h" -#endif - -#ifndef _TVECTOR_H_ -#include "core/util/tVector.h" -#endif - - -/// Audio data buffer for the XAudio device layer. -class SFXXAudioBuffer : public SFXBuffer -{ - public: - - typedef SFXBuffer Parent; - - friend class SFXXAudioDevice; - friend class SFXXAudioVoice; - - protected: - - struct Buffer - { - XAUDIO2_BUFFER mData; - SFXInternal::SFXStreamPacket* mPacket; - - Buffer() - : mPacket( 0 ) - { - dMemset( &mData, 0, sizeof( mData ) ); - } - }; - - typedef Vector< Buffer > QueueType; - - QueueType mBufferQueue; - - /// If this is a streaming buffer, return the unique voice associated - /// with the buffer. - SFXXAudioVoice* _getUniqueVoice() { return ( SFXXAudioVoice* ) mUniqueVoice.getPointer(); } - - /// - SFXXAudioBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ); - virtual ~SFXXAudioBuffer(); - - // SFXBuffer. - virtual void write( SFXInternal::SFXStreamPacket* const* packets, U32 num ); - void _flush(); - - public: - - /// - static SFXXAudioBuffer* create( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ); -}; - -#endif // _SFXXAUDIOBUFFER_H_ \ No newline at end of file diff --git a/Engine/source/sfx/xaudio/sfxXAudioDevice.cpp b/Engine/source/sfx/xaudio/sfxXAudioDevice.cpp deleted file mode 100644 index eca8e64ea..000000000 --- a/Engine/source/sfx/xaudio/sfxXAudioDevice.cpp +++ /dev/null @@ -1,245 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "sfx/xaudio/sfxXAudioDevice.h" -#include "platform/async/asyncUpdate.h" -#include "core/stringTable.h" -#include "console/console.h" -#include "core/util/safeRelease.h" -#include "core/tAlgorithm.h" -#include "platform/profiler.h" - - -SFXXAudioDevice::SFXXAudioDevice( SFXProvider* provider, - const String& name, - IXAudio2 *xaudio, - U32 deviceIndex, - U32 speakerChannelMask, - U32 maxBuffers ) - : Parent( name, provider, false, maxBuffers ), - mXAudio( xaudio ), - mMasterVoice( NULL ) -{ - dMemset( &mListener, 0, sizeof( mListener ) ); - - // If mMaxBuffers is negative then use some default value. - // to decide on a good maximum value... or set 8. - // - // TODO: We should change the terminology to voices! - if ( mMaxBuffers < 0 ) - mMaxBuffers = 64; - - // Create the mastering voice. - HRESULT hr = mXAudio->CreateMasteringVoice( &mMasterVoice, - XAUDIO2_DEFAULT_CHANNELS, - XAUDIO2_DEFAULT_SAMPLERATE, - 0, - deviceIndex, - NULL ); - if ( FAILED( hr ) || !mMasterVoice ) - { - Con::errorf( "SFXXAudioDevice - Failed creating master voice!" ); - return; - } - - mMasterVoice->GetVoiceDetails( &mMasterVoiceDetails ); - - // Init X3DAudio. - X3DAudioInitialize( speakerChannelMask, - X3DAUDIO_SPEED_OF_SOUND, - mX3DAudio ); - - // Start the update thread. - - if( !Con::getBoolVariable( "$_forceAllMainThread" ) ) - { - SFXInternal::gUpdateThread = new AsyncUpdateThread - ( "XAudio Update Thread", SFXInternal::gBufferUpdateList ); - SFXInternal::gUpdateThread->start(); - } -} - - -SFXXAudioDevice::~SFXXAudioDevice() -{ - _releaseAllResources(); - - if ( mMasterVoice ) - { - mMasterVoice->DestroyVoice(); - mMasterVoice = NULL; - } - - // Kill the engine. - SAFE_RELEASE( mXAudio ); -} - - -SFXBuffer* SFXXAudioDevice::createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ) -{ - SFXXAudioBuffer* buffer = SFXXAudioBuffer::create( stream, description ); - if ( !buffer ) - return NULL; - - _addBuffer( buffer ); - return buffer; -} - -SFXVoice* SFXXAudioDevice::createVoice( bool is3D, SFXBuffer *buffer ) -{ - // Don't bother going any further if we've - // exceeded the maximum voices. - if ( mVoices.size() >= mMaxBuffers ) - return NULL; - - AssertFatal( buffer, "SFXXAudioDevice::createVoice() - Got null buffer!" ); - - SFXXAudioBuffer* xaBuffer = dynamic_cast( buffer ); - AssertFatal( xaBuffer, "SFXXAudioDevice::createVoice() - Got bad buffer!" ); - - SFXXAudioVoice* voice = SFXXAudioVoice::create( mXAudio, is3D, xaBuffer ); - if ( !voice ) - return NULL; - - voice->mXAudioDevice = this; - - _addVoice( voice ); - return voice; -} - -void SFXXAudioDevice::_setOutputMatrix( SFXXAudioVoice *voice ) -{ - X3DAUDIO_DSP_SETTINGS dspSettings = {0}; - FLOAT32 matrix[12] = { 0 }; - dspSettings.DstChannelCount = mMasterVoiceDetails.InputChannels; - dspSettings.pMatrixCoefficients = matrix; - - const X3DAUDIO_EMITTER &emitter = voice->getEmitter(); - dspSettings.SrcChannelCount = emitter.ChannelCount; - - // Calculate the output volumes and doppler. - X3DAudioCalculate( mX3DAudio, - &mListener, - &emitter, - X3DAUDIO_CALCULATE_MATRIX | - X3DAUDIO_CALCULATE_DOPPLER, - &dspSettings ); - - voice->mXAudioVoice->SetOutputMatrix( mMasterVoice, - dspSettings.SrcChannelCount, - dspSettings.DstChannelCount, - dspSettings.pMatrixCoefficients, - 4321 ); - - voice->mXAudioVoice->SetFrequencyRatio( dspSettings.DopplerFactor * voice->mPitch, - 4321 ); - - // Commit the changes. - mXAudio->CommitChanges( 4321 ); -} - -void SFXXAudioDevice::update() -{ - PROFILE_SCOPE( SFXXAudioDevice_Update ); - - Parent::update(); - - X3DAUDIO_DSP_SETTINGS dspSettings = {0}; - FLOAT32 matrix[12] = { 0 }; - dspSettings.DstChannelCount = mMasterVoiceDetails.InputChannels; - dspSettings.pMatrixCoefficients = matrix; - - dspSettings.DopplerFactor = mDopplerFactor; - - // Now update the volume and frequency of - // all the active 3D voices. - VoiceVector::iterator voice = mVoices.begin(); - for ( ; voice != mVoices.end(); voice++ ) - { - SFXXAudioVoice* xaVoice = ( SFXXAudioVoice* ) *voice; - - // Skip 2D or stopped voices. - if ( !xaVoice->is3D() || - xaVoice->getStatus() != SFXStatusPlaying ) - continue; - - const X3DAUDIO_EMITTER &emitter = xaVoice->getEmitter(); - dspSettings.SrcChannelCount = emitter.ChannelCount; - - // Calculate the output volumes and doppler. - X3DAudioCalculate( mX3DAudio, - &mListener, - &emitter, - X3DAUDIO_CALCULATE_MATRIX | - X3DAUDIO_CALCULATE_DOPPLER, - &dspSettings ); - - xaVoice->mXAudioVoice->SetOutputMatrix( mMasterVoice, - dspSettings.SrcChannelCount, - dspSettings.DstChannelCount, - dspSettings.pMatrixCoefficients, - 4321 ) ; - - xaVoice->mXAudioVoice->SetFrequencyRatio( dspSettings.DopplerFactor * xaVoice->mPitch, - 4321 ); - } - - // Commit the changes. - mXAudio->CommitChanges( 4321 ); -} - -void SFXXAudioDevice::setListener( U32 index, const SFXListenerProperties& listener ) -{ - // Get the transform from the listener. - const MatrixF& transform = listener.getTransform(); - transform.getColumn( 3, (Point3F*)&mListener.Position ); - transform.getColumn( 1, (Point3F*)&mListener.OrientFront ); - transform.getColumn( 2, (Point3F*)&mListener.OrientTop ); - - // And the velocity... - const VectorF& velocity = listener.getVelocity(); - mListener.Velocity.x = velocity.x; - mListener.Velocity.y = velocity.y; - mListener.Velocity.z = velocity.z; - - // XAudio and Torque use opposite handedness, so - // flip the z coord to account for that. - mListener.Position.z *= -1.0f; - mListener.OrientFront.z *= -1.0f; - mListener.OrientTop.z *= -1.0f; - mListener.Velocity.z *= -1.0f; -} - -void SFXXAudioDevice::setDistanceModel( SFXDistanceModel model ) -{ - mDistanceModel = model; -} - -void SFXXAudioDevice::setDopplerFactor( F32 factor ) -{ - mDopplerFactor = factor; -} - -void SFXXAudioDevice::setRolloffFactor( F32 factor ) -{ - mRolloffFactor = factor; -} diff --git a/Engine/source/sfx/xaudio/sfxXAudioDevice.h b/Engine/source/sfx/xaudio/sfxXAudioDevice.h deleted file mode 100644 index 7e1d8a7ee..000000000 --- a/Engine/source/sfx/xaudio/sfxXAudioDevice.h +++ /dev/null @@ -1,101 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _SFXXAUDIODEVICE_H_ -#define _SFXXAUDIODEVICE_H_ - -class SFXProvider; - -#ifndef _SFXDEVICE_H_ -#include "sfx/sfxDevice.h" -#endif - -#ifndef _SFXPROVIDER_H_ -#include "sfx/sfxProvider.h" -#endif - -#ifndef _SFXXAUDIOVOICE_H_ -#include "sfx/xaudio/sfxXAudioVoice.h" -#endif - -#ifndef _SFXXAUDIOBUFFER_H_ -#include "sfx/xaudio/sfxXAudioBuffer.h" -#endif - -#include -#include - - -class SFXXAudioDevice : public SFXDevice -{ - public: - - typedef SFXDevice Parent; - friend class SFXXAudioVoice; // mXAudio - - protected: - - /// The XAudio engine interface passed - /// on creation from the provider. - IXAudio2 *mXAudio; - - /// The X3DAudio instance. - X3DAUDIO_HANDLE mX3DAudio; - - /// The one and only mastering voice. - IXAudio2MasteringVoice* mMasterVoice; - - /// The details of the master voice. - XAUDIO2_VOICE_DETAILS mMasterVoiceDetails; - - /// The one listener. - X3DAUDIO_LISTENER mListener; - - SFXDistanceModel mDistanceModel; - F32 mRolloffFactor; - F32 mDopplerFactor; - - public: - - SFXXAudioDevice( SFXProvider* provider, - const String& name, - IXAudio2 *xaudio, - U32 deviceIndex, - U32 speakerChannelMask, - U32 maxBuffers ); - - virtual ~SFXXAudioDevice(); - - // SFXDevice - virtual SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description ); - virtual SFXVoice* createVoice( bool is3D, SFXBuffer *buffer ); - virtual void update(); - virtual void setListener( U32 index, const SFXListenerProperties& listener ); - virtual void setDistanceModel( SFXDistanceModel model ); - virtual void setRolloffFactor( F32 factor ); - virtual void setDopplerFactor( F32 factor ); - - /// Called from the voice when its about to start playback. - void _setOutputMatrix( SFXXAudioVoice *voice ); -}; - -#endif // _SFXXAUDIODEVICE_H_ \ No newline at end of file diff --git a/Engine/source/sfx/xaudio/sfxXAudioProvider.cpp b/Engine/source/sfx/xaudio/sfxXAudioProvider.cpp deleted file mode 100644 index ab060ae5e..000000000 --- a/Engine/source/sfx/xaudio/sfxXAudioProvider.cpp +++ /dev/null @@ -1,188 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -// Note: This must be defined before platform.h so that -// CoInitializeEx is properly included. -#define _WIN32_DCOM -#include - -#include "sfx/xaudio/sfxXAudioDevice.h" -#include "sfx/sfxProvider.h" -#include "core/util/safeRelease.h" -#include "core/strings/unicode.h" -#include "core/strings/stringFunctions.h" -#include "console/console.h" -#include "core/module.h" - - -class SFXXAudioProvider : public SFXProvider -{ -public: - - SFXXAudioProvider() - : SFXProvider( "XAudio" ) {} - virtual ~SFXXAudioProvider(); - -protected: - - /// Extended SFXDeviceInfo to also store some - /// extra XAudio specific data. - struct XADeviceInfo : SFXDeviceInfo - { - UINT32 deviceIndex; - - XAUDIO2_DEVICE_ROLE role; - - WAVEFORMATEXTENSIBLE format; - }; - - /// Helper for creating the XAudio engine. - static bool _createXAudio( IXAudio2 **xaudio ); - -public: - - // SFXProvider - void init(); - SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ); - -}; - -MODULE_BEGIN( XAudio ) - - MODULE_INIT_BEFORE( SFX ) - MODULE_SHUTDOWN_AFTER( SFX ) - - SFXXAudioProvider* mProvider; - - MODULE_INIT - { - mProvider = new SFXXAudioProvider; - } - - MODULE_SHUTDOWN - { - delete mProvider; - } - -MODULE_END; - -SFXXAudioProvider::~SFXXAudioProvider() -{ -} - -void SFXXAudioProvider::init() -{ - // Create a temp XAudio object for device enumeration. - IXAudio2 *xAudio = NULL; - if ( !_createXAudio( &xAudio ) ) - { - Con::errorf( "SFXXAudioProvider::init() - XAudio2 failed to load!" ); - return; - } - - // Add the devices to the info list. - UINT32 count = 0; - xAudio->GetDeviceCount( &count ); - for ( UINT32 i = 0; i < count; i++ ) - { - XAUDIO2_DEVICE_DETAILS details; - HRESULT hr = xAudio->GetDeviceDetails( i, &details ); - if ( FAILED( hr ) ) - continue; - - // Add a device to the info list. - XADeviceInfo* info = new XADeviceInfo; - info->deviceIndex = i; - info->driver = String( "XAudio" ); - info->name = String( details.DisplayName ); - info->hasHardware = false; - info->maxBuffers = 64; - info->role = details.Role; - info->format = details.OutputFormat; - mDeviceInfo.push_back( info ); - } - - // We're done with XAudio for now. - SAFE_RELEASE( xAudio ); - - // If we have no devices... we're done. - if ( mDeviceInfo.empty() ) - { - Con::errorf( "SFXXAudioProvider::init() - No valid XAudio2 devices found!" ); - return; - } - - // If we got this far then we should be able to - // safely create a device for XAudio. - regProvider( this ); -} - -bool SFXXAudioProvider::_createXAudio( IXAudio2 **xaudio ) -{ - // In debug builds enable the debug version - // of the XAudio engine. - #ifdef TORQUE_DEBUG - #define XAUDIO_FLAGS XAUDIO2_DEBUG_ENGINE - #else - #define XAUDIO_FLAGS 0 - #endif - - // This must be called first... it doesn't hurt to - // call it more than once. - CoInitialize( NULL ); - - // Try creating the xaudio engine. - HRESULT hr = XAudio2Create( xaudio, XAUDIO_FLAGS, XAUDIO2_DEFAULT_PROCESSOR ); - - return SUCCEEDED( hr ) && (*xaudio); -} - -SFXDevice* SFXXAudioProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers ) -{ - String devName; - - devName = deviceName; - - XADeviceInfo* info = dynamic_cast< XADeviceInfo* >( _findDeviceInfo( devName ) ); - - // Do we find one to create? - if ( info ) - { - // Create the XAudio object to pass to the device. - IXAudio2 *xAudio = NULL; - if ( !_createXAudio( &xAudio ) ) - { - Con::errorf( "SFXXAudioProvider::createDevice() - XAudio2 failed to load!" ); - return NULL; - } - - return new SFXXAudioDevice( this, - devName, - xAudio, - info->deviceIndex, - info->format.dwChannelMask, - maxBuffers ); - } - - // We didn't find a matching valid device. - return NULL; -} diff --git a/Engine/source/sfx/xaudio/sfxXAudioVoice.cpp b/Engine/source/sfx/xaudio/sfxXAudioVoice.cpp deleted file mode 100644 index 80ba7745c..000000000 --- a/Engine/source/sfx/xaudio/sfxXAudioVoice.cpp +++ /dev/null @@ -1,445 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#include "platform/platform.h" -#include "sfx/xaudio/sfxXAudioVoice.h" -#include "sfx/xaudio/sfxXAudioDevice.h" -#include "sfx/xaudio/sfxXAudioBuffer.h" -#include "core/util/safeDelete.h" -#include "math/mMathFn.h" - - -//#define DEBUG_SPEW - - -static void sfxFormatToWAVEFORMATEX( const SFXFormat& format, WAVEFORMATEX *wfx ) -{ - dMemset( wfx, 0, sizeof( WAVEFORMATEX ) ); - wfx->wFormatTag = WAVE_FORMAT_PCM; - wfx->nChannels = format.getChannels(); - wfx->nSamplesPerSec = format.getSamplesPerSecond(); - wfx->wBitsPerSample = format.getBitsPerChannel(); - wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8; - wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign; -} - - -SFXXAudioVoice* SFXXAudioVoice::create( IXAudio2 *xaudio, - bool is3D, - SFXXAudioBuffer *buffer, - SFXXAudioVoice* inVoice ) -{ - AssertFatal( xaudio, "SFXXAudioVoice::create() - Got null XAudio!" ); - AssertFatal( buffer, "SFXXAudioVoice::create() - Got null buffer!" ); - - // Create the voice object first as it also the callback object. - SFXXAudioVoice* voice = inVoice; - if( !voice ) - voice = new SFXXAudioVoice( buffer ); - - // Get the buffer format. - WAVEFORMATEX wfx; - sfxFormatToWAVEFORMATEX( buffer->getFormat(), &wfx ); - - // We don't support multi-channel 3d sounds! - if ( is3D && wfx.nChannels > 1 ) - return NULL; - - // Create the voice. - IXAudio2SourceVoice *xaVoice; - HRESULT hr = xaudio->CreateSourceVoice( &xaVoice, - (WAVEFORMATEX*)&wfx, - 0, - XAUDIO2_DEFAULT_FREQ_RATIO, - voice, - NULL, - NULL ); - - if( FAILED( hr ) || !voice ) - { - if( !inVoice ) - delete voice; - return NULL; - } - - voice->mIs3D = is3D; - voice->mEmitter.ChannelCount = wfx.nChannels; - voice->mXAudioVoice = xaVoice; - - return voice; -} - -SFXXAudioVoice::SFXXAudioVoice( SFXXAudioBuffer* buffer ) - : Parent( buffer ), - mXAudioDevice( NULL ), - mXAudioVoice( NULL ), - mIs3D( false ), - mPitch( 1.0f ), - mHasStopped( false ), - mHasStarted( false ), - mIsLooping( false ), - mIsPlaying( false ), - mNonStreamSampleStartPos( 0 ), - mNonStreamBufferLoaded( false ), - mSamplesPlayedOffset( 0 ) -{ - dMemset( &mEmitter, 0, sizeof( mEmitter ) ); - mEmitter.DopplerScaler = 1.0f; - - InitializeCriticalSection( &mLock ); -} - -SFXXAudioVoice::~SFXXAudioVoice() -{ - if ( mEmitter.pVolumeCurve ) - { - SAFE_DELETE_ARRAY( mEmitter.pVolumeCurve->pPoints ); - SAFE_DELETE( mEmitter.pVolumeCurve ); - } - - SAFE_DELETE( mEmitter.pCone ); - - if ( mXAudioVoice ) - mXAudioVoice->DestroyVoice(); - - DeleteCriticalSection( &mLock ); -} - -SFXStatus SFXXAudioVoice::_status() const -{ - if( mHasStopped ) - return SFXStatusStopped; - else if( mHasStarted ) - { - if( !mIsPlaying ) - return SFXStatusPaused; - else - return SFXStatusPlaying; - } - else - return SFXStatusStopped; -} - -void SFXXAudioVoice::_flush() -{ - AssertFatal( mXAudioVoice != NULL, - "SFXXAudioVoice::_flush() - invalid voice" ); - - EnterCriticalSection( &mLock ); - - mXAudioVoice->Stop( 0 ); - mXAudioVoice->FlushSourceBuffers(); - mNonStreamBufferLoaded = false; - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioVoice] Flushed state" ); - #endif - - mIsPlaying = false; - mHasStarted = false; - mHasStopped = true; - - //WORKAROUND: According to the docs, SamplesPlayed reported by the - // voice should get reset as soon as we submit a new buffer to the voice. - // Alas it won't. So, save the current value here and offset our future - // play cursors. - - XAUDIO2_VOICE_STATE state; - mXAudioVoice->GetState( &state ); - mSamplesPlayedOffset = - S32( state.SamplesPlayed ); - - LeaveCriticalSection( &mLock ); -} - -void SFXXAudioVoice::_play() -{ - AssertFatal( mXAudioVoice != NULL, - "SFXXAudioVoice::_play() - invalid voice" ); - - // For non-streaming voices queue the data if we haven't yet. - - if( !mBuffer->isStreaming() && !mNonStreamBufferLoaded ) - _loadNonStreamed(); - - // Start playback. - - mXAudioVoice->Start( 0, 0 ); - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioVoice] Started playback" ); - #endif - - mIsPlaying = true; - mHasStarted = true; - mHasStopped = false; -} - -void SFXXAudioVoice::_pause() -{ - AssertFatal( mXAudioVoice != NULL, - "SFXXAudioVoice::_pause() - invalid voice" ); - - mXAudioVoice->Stop( 0 ); - mIsPlaying = false; - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioVoice] Paused playback" ); - #endif -} - -void SFXXAudioVoice::_stop() -{ - AssertFatal( mXAudioVoice != NULL, - "SFXXAudioVoice::_stop() - invalid voice" ); - - _flush(); - - mIsPlaying = false; - mHasStarted = false; - mHasStopped = true; - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioVoice] Stopped playback" ); - #endif -} - -void SFXXAudioVoice::_seek( U32 sample ) -{ - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioVoice] Seeking to %i", sample ); - #endif - - mNonStreamSampleStartPos = sample; - - bool wasPlaying = mIsPlaying; - - _stop(); - if( wasPlaying ) - _play(); -} - -void SFXXAudioVoice::_loadNonStreamed() -{ - AssertFatal( !mBuffer->isStreaming(), "SFXXAudioVoice::_loadNonStreamed - must not be called on streaming voices" ); - AssertFatal( mXAudioVoice != NULL, "SFXXAudioVoice::_loadNonStreamed - invalid voice" ); - AssertWarn( !mNonStreamBufferLoaded, "SFXXAudioVoice::_nonStreamNonstreamed - Data already loaded" ); - - #ifdef DEBUG_SPEW - Platform::outputDebugString( "[SFXXAudioVoice] Loading non-stream buffer at %i", mNonStreamSampleStartPos ); - #endif - - EnterCriticalSection( &mLock ); - - const XAUDIO2_BUFFER& orgBuffer = _getBuffer()->mBufferQueue.front().mData; - - mNonStreamBuffer = orgBuffer; - - if( mNonStreamSampleStartPos ) - { - mNonStreamBuffer.PlayBegin = mNonStreamSampleStartPos; - mNonStreamBuffer.PlayLength = _getBuffer()->getNumSamples() - mNonStreamSampleStartPos; - mSamplesPlayedOffset += mNonStreamSampleStartPos; // Add samples that we are skipping. - mNonStreamSampleStartPos = 0; - } - - if( mIsLooping ) - { - mNonStreamBuffer.LoopCount = XAUDIO2_LOOP_INFINITE; - mNonStreamBuffer.LoopLength = _getBuffer()->getNumSamples(); - } - - // Submit buffer. - - mXAudioVoice->SubmitSourceBuffer( &mNonStreamBuffer ); - mNonStreamBufferLoaded = true; - - LeaveCriticalSection( &mLock ); -} - -U32 SFXXAudioVoice::_tell() const -{ - XAUDIO2_VOICE_STATE state; - mXAudioVoice->GetState( &state ); - - // Workaround SamplesPlayed not getting reset. - return ( state.SamplesPlayed + mSamplesPlayedOffset ); -} - -void SFXXAudioVoice::setMinMaxDistance( F32 min, F32 max ) -{ - // Set the overall volume curve scale. - mEmitter.CurveDistanceScaler = max; - - // The curve uses normalized distances, so - // figure out the normalized min distance. - F32 normMin = 0.0f; - if ( min > 0.0f ) - normMin = min / max; - - // See what type of curve we are supposed to generate. - const bool linear = ( mXAudioDevice->mDistanceModel == SFXDistanceModelLinear ); - - // Have we setup the curve yet? - if( !mEmitter.pVolumeCurve - || ( linear && mEmitter.pVolumeCurve->PointCount != 2 ) - || ( !linear && mEmitter.pVolumeCurve->PointCount != 6 ) ) - { - if( !mEmitter.pVolumeCurve ) - mEmitter.pVolumeCurve = new X3DAUDIO_DISTANCE_CURVE; - else - SAFE_DELETE_ARRAY( mEmitter.pVolumeCurve->pPoints ); - - // We use 6 points for logarithmic volume curves and 2 for linear volume curves. - if( linear ) - { - mEmitter.pVolumeCurve->pPoints = new X3DAUDIO_DISTANCE_CURVE_POINT[ 2 ]; - mEmitter.pVolumeCurve->PointCount = 2; - } - else - { - mEmitter.pVolumeCurve->pPoints = new X3DAUDIO_DISTANCE_CURVE_POINT[ 6 ]; - mEmitter.pVolumeCurve->PointCount = 6; - } - - // The first and last points are known - // and will not change. - mEmitter.pVolumeCurve->pPoints[ 0 ].Distance = 0.0f; - mEmitter.pVolumeCurve->pPoints[ 0 ].DSPSetting = 1.0f; - mEmitter.pVolumeCurve->pPoints[ linear ? 1 : 5 ].Distance = 1.0f; - mEmitter.pVolumeCurve->pPoints[ linear ? 1 : 5 ].DSPSetting = 0.0f; - } - - if( !linear ) - { - // Set the second point of the curve. - mEmitter.pVolumeCurve->pPoints[1].Distance = normMin; - mEmitter.pVolumeCurve->pPoints[1].DSPSetting = 1.0f; - - // The next three points are calculated to - // give the sound a rough logarithmic falloff. - F32 distStep = ( 1.0f - normMin ) / 4.0f; - for ( U32 i=0; i < 3; i++ ) - { - U32 index = 2 + i; - F32 dist = normMin + ( distStep * (F32)( i + 1 ) ); - - mEmitter.pVolumeCurve->pPoints[index].Distance = dist; - mEmitter.pVolumeCurve->pPoints[index].DSPSetting = 1.0f - log10( dist * 10.0f ); - } - } -} - -void SFXXAudioVoice::OnBufferEnd( void* bufferContext ) -{ - if( mBuffer->isStreaming() ) - SFXInternal::TriggerUpdate(); -} - -void SFXXAudioVoice::OnStreamEnd() -{ - // Warning: This is being called within the XAudio - // thread, so be sure you're thread safe! - - mHasStopped = true; - - if( mBuffer->isStreaming() ) - SFXInternal::TriggerUpdate(); - else - _stop(); -} - -void SFXXAudioVoice::play( bool looping ) -{ - // Give the device a chance to calculate our positional - // audio settings before we start playback... this is - // important else we get glitches. - if( mIs3D ) - mXAudioDevice->_setOutputMatrix( this ); - - mIsLooping = looping; - Parent::play( looping ); -} - -void SFXXAudioVoice::setVelocity( const VectorF& velocity ) -{ - mEmitter.Velocity.x = velocity.x; - mEmitter.Velocity.y = velocity.y; - - // XAudio and Torque use opposite handedness, so - // flip the z coord to account for that. - mEmitter.Velocity.z = -velocity.z; -} - -void SFXXAudioVoice::setTransform( const MatrixF& transform ) -{ - transform.getColumn( 3, (Point3F*)&mEmitter.Position ); - transform.getColumn( 1, (Point3F*)&mEmitter.OrientFront ); - transform.getColumn( 2, (Point3F*)&mEmitter.OrientTop ); - - // XAudio and Torque use opposite handedness, so - // flip the z coord to account for that. - mEmitter.Position.z *= -1.0f; - mEmitter.OrientFront.z *= -1.0f; - mEmitter.OrientTop.z *= -1.0f; -} - -void SFXXAudioVoice::setVolume( F32 volume ) -{ - mXAudioVoice->SetVolume( volume ); -} - -void SFXXAudioVoice::setPitch( F32 pitch ) -{ - mPitch = mClampF( pitch, XAUDIO2_MIN_FREQ_RATIO, XAUDIO2_DEFAULT_FREQ_RATIO ); - mXAudioVoice->SetFrequencyRatio( mPitch ); -} - -void SFXXAudioVoice::setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume ) -{ - // If the cone is set to 360 then the - // cone is null and doesn't need to be - // set on the voice. - if ( mIsEqual( innerAngle, 360 ) ) - { - SAFE_DELETE( mEmitter.pCone ); - return; - } - - if ( !mEmitter.pCone ) - { - mEmitter.pCone = new X3DAUDIO_CONE; - - // The inner volume is always 1... the overall - // volume is what scales it. - mEmitter.pCone->InnerVolume = 1.0f; - - // We don't use these yet. - mEmitter.pCone->InnerLPF = 0.0f; - mEmitter.pCone->OuterLPF = 0.0f; - mEmitter.pCone->InnerReverb = 0.0f; - mEmitter.pCone->OuterReverb = 0.0f; - } - - mEmitter.pCone->InnerAngle = mDegToRad( innerAngle ); - mEmitter.pCone->OuterAngle = mDegToRad( outerAngle ); - mEmitter.pCone->OuterVolume = outerVolume; -} diff --git a/Engine/source/sfx/xaudio/sfxXAudioVoice.h b/Engine/source/sfx/xaudio/sfxXAudioVoice.h deleted file mode 100644 index 93500fcc4..000000000 --- a/Engine/source/sfx/xaudio/sfxXAudioVoice.h +++ /dev/null @@ -1,154 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -#ifndef _SFXXAUDIOVOICE_H_ -#define _SFXXAUDIOVOICE_H_ - -#include -#include - -#include "sfx/sfxVoice.h" - - -class SFXXAudioBuffer; - - -class SFXXAudioVoice : public SFXVoice, - public IXAudio2VoiceCallback -{ - public: - - typedef SFXVoice Parent; - - friend class SFXXAudioDevice; - friend class SFXXAudioBuffer; - - protected: - - /// This constructor does not create a valid voice. - /// @see SFXXAudioVoice::create - SFXXAudioVoice( SFXXAudioBuffer* buffer ); - - /// The device that created us. - SFXXAudioDevice *mXAudioDevice; - - /// The XAudio voice. - IXAudio2SourceVoice *mXAudioVoice; - - /// - CRITICAL_SECTION mLock; - - /// Used to know what sounds need positional updates. - bool mIs3D; - - /// Whether the voice has stopped playing. - mutable bool mHasStopped; - - /// Whether we have started playback. - bool mHasStarted; - - /// Whether playback is currently running. - bool mIsPlaying; - - /// Whether playback is looping. - bool mIsLooping; - - /// Since 3D sounds are pitch shifted for doppler - /// effect we need to track the users base pitch. - F32 mPitch; - - /// The cached X3DAudio emitter data. - X3DAUDIO_EMITTER mEmitter; - - /// XAudio does not reset the SamplesPlayed count as is stated in the docs. To work around - /// that, we offset the values reported by XAudio through this field. - S32 mSamplesPlayedOffset; - - /// @name Data for Non-Streaming Voices - /// @{ - - /// Whether we have loaded our non-streaming data. We use an explicit - /// flag here as we really can't rely on XAUDIO2_VOICE_STATE. - bool mNonStreamBufferLoaded; - - /// Audio buffer for non-streaming voice. - XAUDIO2_BUFFER mNonStreamBuffer; - - /// Sample to start playing at when seting up #mNonStreamBuffer. - U32 mNonStreamSampleStartPos; - - /// @} - - // IXAudio2VoiceCallback - void STDMETHODCALLTYPE OnStreamEnd(); - void STDMETHODCALLTYPE OnVoiceProcessingPassStart( UINT32 BytesRequired ) {} - void STDMETHODCALLTYPE OnVoiceProcessingPassEnd() {} - void STDMETHODCALLTYPE OnBufferEnd( void *bufferContext ); - void STDMETHODCALLTYPE OnBufferStart( void *bufferContext ) {} - void STDMETHODCALLTYPE OnLoopEnd( void *bufferContext ) {} - void STDMETHODCALLTYPE OnVoiceError( void * bufferContext, HRESULT error ) {} - - /// @deprecated This is only here for compatibility with - /// the March 2008 SDK version of IXAudio2VoiceCallback. - void STDMETHODCALLTYPE OnVoiceProcessingPassStart() {} - - void _flush(); - void _loadNonStreamed(); - - // SFXVoice. - virtual SFXStatus _status() const; - virtual void _play(); - virtual void _pause(); - virtual void _stop(); - virtual void _seek( U32 sample ); - virtual U32 _tell() const; - - SFXXAudioBuffer* _getBuffer() const { return ( SFXXAudioBuffer* ) mBuffer.getPointer(); } - - public: - - /// - static SFXXAudioVoice* create( IXAudio2 *xaudio, - bool is3D, - SFXXAudioBuffer *buffer, - SFXXAudioVoice* inVoice = NULL ); - - /// - virtual ~SFXXAudioVoice(); - - // SFXVoice - void setMinMaxDistance( F32 min, F32 max ); - void play( bool looping ); - void setVelocity( const VectorF& velocity ); - void setTransform( const MatrixF& transform ); - void setVolume( F32 volume ); - void setPitch( F32 pitch ); - void setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume ); - - /// Is this a 3D positional voice. - bool is3D() const { return mIs3D; } - - /// - const X3DAUDIO_EMITTER& getEmitter() const { return mEmitter; } -}; - -#endif // _SFXXAUDIOVOICE_H_ \ No newline at end of file diff --git a/Templates/BaseGame/game/core/core.tscript b/Templates/BaseGame/game/core/core.tscript index 09f278e03..e6232dc73 100644 --- a/Templates/BaseGame/game/core/core.tscript +++ b/Templates/BaseGame/game/core/core.tscript @@ -70,9 +70,7 @@ function CoreModule::onCreate(%this) // Init the physics plugin. physicsInit(); - - sfxStartup(); - + // Set up networking. setNetPort(0); diff --git a/Templates/BaseGame/game/core/sfx/Core_SFX.tscript b/Templates/BaseGame/game/core/sfx/Core_SFX.tscript index 771048b32..81a6b952b 100644 --- a/Templates/BaseGame/game/core/sfx/Core_SFX.tscript +++ b/Templates/BaseGame/game/core/sfx/Core_SFX.tscript @@ -3,10 +3,10 @@ function Core_SFX::onCreate(%this) { exec("./scripts/audio." @ $TorqueScriptFileExtension); exec("./scripts/audioData." @ $TorqueScriptFileExtension); + exec("./scripts/audioStates." @ $TorqueScriptFileExtension); + exec("./scripts/audioEnvironments." @ $TorqueScriptFileExtension); exec("./scripts/audioAmbience." @ $TorqueScriptFileExtension); exec("./scripts/audioDescriptions." @ $TorqueScriptFileExtension); - exec("./scripts/audioEnvironments." @ $TorqueScriptFileExtension); - exec("./scripts/audioStates." @ $TorqueScriptFileExtension); exec("./scripts/audioOptions." @ $TorqueScriptFileExtension); } diff --git a/Templates/BaseGame/game/core/sfx/scripts/audio.tscript b/Templates/BaseGame/game/core/sfx/scripts/audio.tscript index 2d8726afc..954b6a35b 100644 --- a/Templates/BaseGame/game/core/sfx/scripts/audio.tscript +++ b/Templates/BaseGame/game/core/sfx/scripts/audio.tscript @@ -145,10 +145,6 @@ function sfxStartup() function sfxInit() { // If already initialized, shut down the current device first. - - if( sfxGetDeviceInfo() !$= "" ) - sfxShutdown(); - if ($isDedicated) { sfxCreateDevice("Null","Null Device", false, 8); @@ -156,12 +152,16 @@ function sfxInit() } // Start it up! - %maxBuffers = $pref::SFX::useHardware ? -1 : $pref::SFX::maxSoftwareBuffers; - if ( !sfxCreateDevice( $pref::SFX::provider, $pref::SFX::device, $pref::SFX::useHardware, %maxBuffers ) ) - return false; + %info = sfxGetDeviceInfo(); + if(%info $= "" ) + { + %maxBuffers = $pref::SFX::useHardware ? -1 : $pref::SFX::maxSoftwareBuffers; + if ( !sfxCreateDevice() ) + return false; + } // This returns a tab seperated string with - // the initialized system info. + // the initialized system info %info = sfxGetDeviceInfo(); $pref::SFX::provider = getField( %info, 0 ); $pref::SFX::device = getField( %info, 1 ); diff --git a/Templates/BaseGame/game/core/sfx/scripts/audioAmbience.tscript b/Templates/BaseGame/game/core/sfx/scripts/audioAmbience.tscript index 8c2bf270c..4b45ee113 100644 --- a/Templates/BaseGame/game/core/sfx/scripts/audioAmbience.tscript +++ b/Templates/BaseGame/game/core/sfx/scripts/audioAmbience.tscript @@ -23,22 +23,27 @@ singleton SFXAmbience( AudioAmbienceDefault ) { environment = AudioEnvOff; + dopplerFactor = "1"; }; singleton SFXAmbience( AudioAmbienceOutside ) { environment = AudioEnvPlain; states[ 0 ] = AudioLocationOutside; + dopplerFactor = "1"; }; singleton SFXAmbience( AudioAmbienceInside ) { environment = AudioEnvRoom; states[ 0 ] = AudioLocationInside; + dopplerFactor = "1"; }; singleton SFXAmbience( AudioAmbienceUnderwater ) { environment = AudioEnvUnderwater; states[ 0 ] = AudioLocationUnderwater; + dopplerFactor = "0.5"; + speedOfSound = "1500.0"; }; diff --git a/Templates/BaseGame/game/core/sfx/scripts/audioOptions.tscript b/Templates/BaseGame/game/core/sfx/scripts/audioOptions.tscript index eb72c3f86..8ac4da6c1 100644 --- a/Templates/BaseGame/game/core/sfx/scripts/audioOptions.tscript +++ b/Templates/BaseGame/game/core/sfx/scripts/audioOptions.tscript @@ -6,8 +6,8 @@ new SimGroup(AudioSettingsGroup) new SimGroup() { class = "SubOptionsGroup"; - displayName = "Audio Devices"; - + displayName = "Audio Settings"; + new SimGroup(AudioSettingsProviderGroup) { class = "AudioOptionsSettings"; @@ -15,7 +15,7 @@ new SimGroup(AudioSettingsGroup) OptionName = "Audio Provider"; Description = ""; }; - + new SimGroup(AudioSettingsDeviceGroup) { class = "AudioOptionsSettings"; @@ -31,43 +31,40 @@ function AudioSettingsGroup::populateSettings(%this) AudioSettingsProviderGroup.clear(); AudioSettingsDeviceGroup.clear(); - %buffer = sfxGetAvailableDevices(); - %count = getRecordCount( %buffer ); - - for(%i = 0; %i < %count; %i++) + %pCount = sfxGetProviderCount(); + for(%i = 0; %i < %pCount; %i++) { - %record = getRecord(%buffer, %i); - %provider = getField(%record, 0); - %device = getField(%record, 1); - - //When the client is actually running, we don't care about null audo devices - if(%provider $= "null") - continue; - - //We can't have duplicate providers, so double check for uniqueness - %foundProvider = false; - foreach(%registeredProviders in AudioSettingsProviderGroup) + %provider = sfxGetProviderType(%i); + if(%provider !$= "NullProvider") { - if(%registeredProviders.displayName $= %provider) + //We can't have duplicate providers, so double check for uniqueness + %foundProvider = false; + foreach(%registeredProviders in AudioSettingsProviderGroup) { - %foundProvider = true; - break; + if(%registeredProviders.displayName $= %provider) + { + %foundProvider = true; + break; + } + } + + if(!%foundProvider) + { + //Provider entry + %providerEntry = new ArrayObject() + { + class = "OptionsQualityLevel"; + displayName = %provider; + key["$pref::SFX::provider"] = %provider; + }; + AudioSettingsProviderGroup.add(%providerEntry); } } - - if(!%foundProvider) - { - //Provider entry - %providerEntry = new ArrayObject() - { - class = "OptionsQualityLevel"; - displayName = %provider; - key["$pref::SFX::provider"] = %provider; - }; - - AudioSettingsProviderGroup.add(%providerEntry); - } - + } + + for(%i = 0; %i < %pCount; %i++) + { + %device = sfxGetProviderDevice(%i); //Device Entry %deviceEntry = new ArrayObject() { @@ -93,10 +90,7 @@ function AudioSettingsDeviceGroup::onApply(%this) function updateAudioOptionsSettings() { - if ( !sfxCreateDevice( $pref::SFX::provider, - $pref::SFX::device, - $pref::SFX::useHardware, - -1 ) ) + if ( !sfxCreateDevice() ) error( "Unable to create SFX device: " @ $pref::SFX::provider SPC $pref::SFX::device SPC $pref::SFX::useHardware ); diff --git a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript index f502982ad..49fe38a91 100644 --- a/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript +++ b/Templates/BaseGame/game/data/UI/guis/optionsMenu.tscript @@ -223,7 +223,6 @@ function OptionsMenu::openOptionsCategory(%this, %categoryName) else if(%categoryName $= "Audio") { $MenuList = AudioSettingsList; - %this.currentCatgeoryIdx = 1; } else if(%categoryName $= "KBM") diff --git a/Tools/CMake/modules/dsound.cmake b/Tools/CMake/modules/dsound.cmake deleted file mode 100644 index f91225d39..000000000 --- a/Tools/CMake/modules/dsound.cmake +++ /dev/null @@ -1,8 +0,0 @@ -# OpenAL module -option(TORQUE_SFX_DIRECTX "Use DirectSound SFX" OFF) - -if(TORQUE_SFX_DIRECTX AND WIN32) - message("Enabling DirectSound Module") - - torqueAddSourceDirectories("${CMAKE_SOURCE_DIR}/Engine/source/sfx/dsound" "${CMAKE_SOURCE_DIR}/Engine/source/sfx/xaudio") -endif(TORQUE_SFX_DIRECTX AND WIN32)