mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-19 19:35:26 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
238
Engine/source/sfx/openal/sfxALBuffer.cpp
Normal file
238
Engine/source/sfx/openal/sfxALBuffer.cpp
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// 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/openal/sfxALBuffer.h"
|
||||
#include "sfx/openal/sfxALVoice.h"
|
||||
#include "sfx/openal/sfxALDevice.h"
|
||||
#include "sfx/sfxDescription.h"
|
||||
#include "console/console.h"
|
||||
|
||||
|
||||
//#define DEBUG_SPEW
|
||||
|
||||
|
||||
SFXALBuffer* SFXALBuffer::create( const OPENALFNTABLE &oalft,
|
||||
const ThreadSafeRef< SFXStream >& stream,
|
||||
SFXDescription* description,
|
||||
bool useHardware )
|
||||
{
|
||||
if( !_sfxFormatToALFormat( stream->getFormat() ) )
|
||||
{
|
||||
Con::errorf( "SFXALBuffer::create() - SFXFormat not supported by OpenAL" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SFXALBuffer *buffer = new SFXALBuffer( oalft,
|
||||
stream,
|
||||
description,
|
||||
useHardware );
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
SFXALBuffer::SFXALBuffer( const OPENALFNTABLE &oalft,
|
||||
const ThreadSafeRef< SFXStream >& stream,
|
||||
SFXDescription* description,
|
||||
bool useHardware )
|
||||
: Parent( stream, description ),
|
||||
mOpenAL( oalft ),
|
||||
mUseHardware( useHardware ),
|
||||
mIs3d( description->mIs3D )
|
||||
{
|
||||
// Set up device buffers.
|
||||
|
||||
if( !isStreaming() )
|
||||
mOpenAL.alGenBuffers( 1, &mALBuffer );
|
||||
}
|
||||
|
||||
SFXALBuffer::~SFXALBuffer()
|
||||
{
|
||||
if( _getUniqueVoice() )
|
||||
_getUniqueVoice()->stop();
|
||||
|
||||
// Release buffers.
|
||||
if ( mOpenAL.alIsBuffer( mALBuffer ))
|
||||
mOpenAL.alDeleteBuffers( 1, &mALBuffer );
|
||||
|
||||
while( mFreeBuffers.size() )
|
||||
{
|
||||
ALuint buffer = mFreeBuffers.last();
|
||||
mOpenAL.alDeleteBuffers( 1, &buffer );
|
||||
mFreeBuffers.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void SFXALBuffer::write( SFXInternal::SFXStreamPacket* const* packets, U32 num )
|
||||
{
|
||||
using namespace SFXInternal;
|
||||
|
||||
if( !num )
|
||||
return;
|
||||
|
||||
// If this is not a streaming buffer, just load the data into our single
|
||||
// static buffer.
|
||||
|
||||
if( !isStreaming() )
|
||||
{
|
||||
SFXStreamPacket* packet = packets[ num - 1 ];
|
||||
|
||||
ALenum alFormat = _sfxFormatToALFormat( getFormat() );
|
||||
AssertFatal( alFormat != 0, "SFXALBuffer::write() - format unsupported" );
|
||||
|
||||
mOpenAL.alBufferData( mALBuffer, alFormat,
|
||||
packet->data, packet->mSizeActual, getFormat().getSamplesPerSecond() );
|
||||
|
||||
destructSingle( packet );
|
||||
return;
|
||||
}
|
||||
|
||||
MutexHandle mutex;
|
||||
mutex.lock( &_getUniqueVoice()->mMutex, true );
|
||||
|
||||
// Unqueue processed packets.
|
||||
|
||||
ALuint source = _getUniqueVoice()->mSourceName;
|
||||
ALint numProcessed;
|
||||
mOpenAL.alGetSourcei( source, AL_BUFFERS_PROCESSED, &numProcessed );
|
||||
|
||||
for( U32 i = 0; i < numProcessed; ++ i )
|
||||
{
|
||||
// Unqueue the buffer.
|
||||
|
||||
ALuint buffer;
|
||||
mOpenAL.alSourceUnqueueBuffers( source, 1, &buffer );
|
||||
|
||||
// Update the sample offset on the voice.
|
||||
|
||||
ALint size;
|
||||
mOpenAL.alGetBufferi( buffer, AL_SIZE, &size );
|
||||
_getUniqueVoice()->mSampleOffset += size / getFormat().getBytesPerSample();
|
||||
|
||||
// Push the buffer onto the freelist.
|
||||
|
||||
mFreeBuffers.push_back( buffer );
|
||||
}
|
||||
|
||||
// Queue buffers.
|
||||
|
||||
for( U32 i = 0; i < num; ++ i )
|
||||
{
|
||||
SFXStreamPacket* packet = packets[ i ];
|
||||
|
||||
// Allocate a buffer.
|
||||
|
||||
ALuint buffer;
|
||||
if( mFreeBuffers.size() )
|
||||
{
|
||||
buffer = mFreeBuffers.last();
|
||||
mFreeBuffers.pop_back();
|
||||
}
|
||||
else
|
||||
mOpenAL.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" );
|
||||
|
||||
mOpenAL.alBufferData( buffer, alFormat,
|
||||
packet->data, packet->mSizeActual, getFormat().getSamplesPerSecond() );
|
||||
|
||||
destructSingle( packet );
|
||||
|
||||
// Queue the buffer.
|
||||
|
||||
mOpenAL.alSourceQueueBuffers( source, 1, &buffer );
|
||||
}
|
||||
}
|
||||
|
||||
void SFXALBuffer::_flush()
|
||||
{
|
||||
AssertFatal( isStreaming(), "SFXALBuffer::_flush() - not a streaming buffer" );
|
||||
AssertFatal( SFXInternal::isSFXThread(), "SFXALBuffer::_flush() - not on SFX thread" );
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString( "[SFXALBuffer] Flushing buffer" );
|
||||
#endif
|
||||
|
||||
_getUniqueVoice()->_stop();
|
||||
|
||||
MutexHandle mutex;
|
||||
mutex.lock( &_getUniqueVoice()->mMutex, true );
|
||||
|
||||
ALuint source = _getUniqueVoice()->mSourceName;
|
||||
|
||||
ALint numQueued;
|
||||
mOpenAL.alGetSourcei( source, AL_BUFFERS_QUEUED, &numQueued );
|
||||
|
||||
for( U32 i = 0; i < numQueued; ++ i )
|
||||
{
|
||||
ALuint buffer;
|
||||
mOpenAL.alSourceUnqueueBuffers( source, 1, &buffer );
|
||||
mFreeBuffers.push_back( buffer );
|
||||
}
|
||||
|
||||
_getUniqueVoice()->mSampleOffset = 0;
|
||||
|
||||
//RD: disabling hack for now; rewritten queueing should be able to cope
|
||||
#if 0 //def TORQUE_OS_MAC
|
||||
|
||||
//WORKAROUND: Ugly hack on Mac. Apparently there's a bug in the OpenAL implementation
|
||||
// that will cause AL_BUFFERS_PROCESSED to not be reset as it should be causing write()
|
||||
// to fail. Brute-force this and just re-create the source. Let's pray that nobody
|
||||
// issues any concurrent state changes on the voice resulting in us losing state here.
|
||||
|
||||
ALuint newSource;
|
||||
mOpenAL.alGenSources( 1, &newSource );
|
||||
|
||||
#define COPY_F( name ) \
|
||||
{ \
|
||||
F32 val; \
|
||||
mOpenAL.alGetSourcef( source, name, &val ); \
|
||||
mOpenAL.alSourcef( source, name, val ); \
|
||||
}
|
||||
|
||||
#define COPY_FV( name ) \
|
||||
{ \
|
||||
VectorF val; \
|
||||
mOpenAL.alGetSourcefv( source, name, val ); \
|
||||
mOpenAL.alSourcefv( source, name, val ); \
|
||||
}
|
||||
|
||||
COPY_F( AL_REFERENCE_DISTANCE );
|
||||
COPY_F( AL_MAX_DISTANCE );
|
||||
COPY_F( AL_GAIN );
|
||||
COPY_F( AL_PITCH );
|
||||
COPY_F( AL_CONE_INNER_ANGLE );
|
||||
COPY_F( AL_CONE_OUTER_ANGLE );
|
||||
COPY_F( AL_CONE_OUTER_GAIN );
|
||||
|
||||
COPY_FV( AL_VELOCITY );
|
||||
COPY_FV( AL_POSITION );
|
||||
COPY_FV( AL_DIRECTION );
|
||||
|
||||
_getUniqueVoice()->mSourceName = newSource;
|
||||
mOpenAL.alDeleteSources( 1, &source );
|
||||
|
||||
#endif
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue