Beispiel #1
0
/*
====================
idSampleDecoder::GetNumUsedBlocks
====================
*/
int idSampleDecoder::GetNumUsedBlocks( void ) {
	return decoderMemoryAllocator.GetNumUsedBlocks();
}
Beispiel #2
0
/*
====================
idSampleDecoder::GetUsedBlockMemory
====================
*/
int idSampleDecoder::GetUsedBlockMemory( void ) {
	return decoderMemoryAllocator.GetUsedBlockMemory();
}
Beispiel #3
0
/*
====================
idSampleDecoder::Init
====================
*/
void idSampleDecoder::Init( void ) {
	decoderMemoryAllocator.Init();
	decoderMemoryAllocator.SetLockMemory( true );
	decoderMemoryAllocator.SetFixedBlocks( idSoundSystemLocal::s_realTimeDecoding.GetBool() ? 10 : 1 );
}
Beispiel #4
0
/*
====================
idSampleDecoder::Shutdown
====================
*/
void idSampleDecoder::Shutdown( void ) {
	decoderMemoryAllocator.Shutdown();
	sampleDecoderAllocator.Shutdown();
}
Beispiel #5
0
void *_decoder_realloc( void *memblock, size_t size ) {
	void *ptr = decoderMemoryAllocator.Resize( (byte *)memblock, size );
	assert( size == 0 || ptr != NULL );
	return ptr;
}
Beispiel #6
0
void _decoder_free( void *memblock ) {
	decoderMemoryAllocator.Free( (byte *)memblock );
}
Beispiel #7
0
void *_decoder_malloc( size_t size ) {
	void *ptr = decoderMemoryAllocator.Alloc( size );
	assert( size == 0 || ptr != NULL );
	return ptr;
}
Beispiel #8
0
void *_decoder_calloc( size_t num, size_t size ) {
	void *ptr = decoderMemoryAllocator.Alloc( num * size );
	assert( ( num * size ) == 0 || ptr != NULL );
	memset( ptr, 0, num * size );
	return ptr;
}
Beispiel #9
0
/*
================
idStr::PurgeMemory
================
*/
void idStr::PurgeMemory( void ) {
#ifdef USE_STRING_DATA_ALLOCATOR
	stringDataAllocator.FreeEmptyBaseBlocks();
#endif
}
Beispiel #10
0
/*
====================
idSampleDecoderLocal::DecodeOGG
====================
*/
int idSampleDecoderLocal::DecodeOGG( idSoundSample *sample, int sampleOffset44k, int sampleCount44k, float *dest ) {
	int readSamples, totalSamples;

	int shift = 22050 / sample->objectInfo.nSamplesPerSec;
	int sampleOffset = sampleOffset44k >> shift;
	int sampleCount = sampleCount44k >> shift;

	// open OGG file if not yet opened
	if ( lastSample == NULL ) {
		// make sure there is enough space for another decoder
		if ( decoderMemoryAllocator.GetFreeBlockMemory() < MIN_OGGVORBIS_MEMORY ) {
			return 0;
		}
		if ( sample->nonCacheData == NULL ) {
			assert( false );	// this should never happen
			failed = true;
			return 0;
		}
		file.SetData( (const char *)sample->nonCacheData, sample->objectMemSize );
		if ( ov_openFile( &file, &ogg ) < 0 ) {
			failed = true;
			return 0;
		}
		lastFormat = WAVE_FORMAT_TAG_OGG;
		lastSample = sample;
	}

	// seek to the right offset if necessary
	if ( sampleOffset != lastSampleOffset ) {
		if ( ov_pcm_seek( &ogg, sampleOffset / sample->objectInfo.nChannels ) != 0 ) {
			failed = true;
			return 0;
		}
	}

	lastSampleOffset = sampleOffset;

	// decode OGG samples
	totalSamples = sampleCount;
	readSamples = 0;
	do {
		float **samples;
		int ret = ov_read_float( &ogg, &samples, totalSamples / sample->objectInfo.nChannels, NULL );
		if ( ret == 0 ) {
			failed = true;
			break;
		}
		if ( ret < 0 ) {
			failed = true;
			return 0;
		}
		ret *= sample->objectInfo.nChannels;

		SIMDProcessor->UpSampleOGGTo44kHz( dest + ( readSamples << shift ), samples, ret, sample->objectInfo.nSamplesPerSec, sample->objectInfo.nChannels );

		readSamples += ret;
		totalSamples -= ret;
	} while( totalSamples > 0 );

	lastSampleOffset += readSamples;

	return ( readSamples << shift );
}
Beispiel #11
0
/*
================
idStr::ShutdownMemory
================
*/
void idStr::ShutdownMemory( void ) {
#ifdef USE_STRING_DATA_ALLOCATOR
	stringDataAllocator.Shutdown();
#endif
}
Beispiel #12
0
/*
================
idStr::InitMemory
================
*/
void idStr::InitMemory( void ) {
#ifdef USE_STRING_DATA_ALLOCATOR
	stringDataAllocator.Init();
#endif
}
Beispiel #13
0
===========================================================================
*/

#include "sys/platform.h"
#include "idlib/math/Vector.h"
#include "idlib/Heap.h"
#include "framework/Common.h"

#include "idlib/Str.h"

#if !defined( ID_REDIRECT_NEWDELETE ) && !defined( MACOS_X )
	#define USE_STRING_DATA_ALLOCATOR
#endif

#ifdef USE_STRING_DATA_ALLOCATOR
static idDynamicBlockAlloc<char, 1<<18, 128>	stringDataAllocator;
#endif

idVec4	g_color_table[16] =
{
	idVec4(0.0f, 0.0f, 0.0f, 1.0f),
	idVec4(1.0f, 0.0f, 0.0f, 1.0f), // S_COLOR_RED
	idVec4(0.0f, 1.0f, 0.0f, 1.0f), // S_COLOR_GREEN
	idVec4(1.0f, 1.0f, 0.0f, 1.0f), // S_COLOR_YELLOW
	idVec4(0.0f, 0.0f, 1.0f, 1.0f), // S_COLOR_BLUE
	idVec4(0.0f, 1.0f, 1.0f, 1.0f), // S_COLOR_CYAN
	idVec4(1.0f, 0.0f, 1.0f, 1.0f), // S_COLOR_MAGENTA
	idVec4(1.0f, 1.0f, 1.0f, 1.0f), // S_COLOR_WHITE
	idVec4(0.5f, 0.5f, 0.5f, 1.0f), // S_COLOR_GRAY
	idVec4(0.0f, 0.0f, 0.0f, 1.0f), // S_COLOR_BLACK
	idVec4(0.0f, 0.0f, 0.0f, 1.0f),
Beispiel #14
0
/*
===================
idSoundCache::~idSoundCache ()
===================
*/
idSoundCache::~idSoundCache()
{
	listCache.DeleteContents( true );
	soundCacheAllocator.Shutdown();
}
Beispiel #15
0
/*
===================
idSoundSample::Load

Loads based on name, possibly doing a MakeDefault if necessary
===================
*/
void idSoundSample::Load( void )
{
	defaultSound = false;
	purged = false;
	hardwareBuffer = false;
	
	timestamp = GetNewTimeStamp();
	
	if( timestamp == FILE_NOT_FOUND_TIMESTAMP )
	{
		common->DWarning( "Couldn't load sound '%s' using default", name.c_str() );
		MakeDefault();
		return;
	}
	
	// load it
	idWaveFile		fh;
	waveformatex_t	info;
	
	if( fh.Open( name, &info ) == -1 )
	{
		common->DWarning( "Couldn't load sound '%s' using default", name.c_str() );
		MakeDefault();
		return;
	}
	
	if( info.nChannels != 1 && info.nChannels != 2 )
	{
		common->DWarning( "idSoundSample: %s has %i channels, using default", name.c_str(), info.nChannels );
		fh.Close();
		MakeDefault();
		return;
	}
	
	if( info.wBitsPerSample != 16 )
	{
		common->DWarning( "idSoundSample: %s is %dbits, expected 16bits using default", name.c_str(), info.wBitsPerSample );
		fh.Close();
		MakeDefault();
		return;
	}
	
	if( info.nSamplesPerSec != 44100 && info.nSamplesPerSec != 22050 && info.nSamplesPerSec != 11025 )
	{
		common->DWarning( "idSoundCache: %s is %dHz, expected 11025, 22050 or 44100 Hz. Using default", name.c_str(), info.nSamplesPerSec );
		fh.Close();
		MakeDefault();
		return;
	}
	objectInfo = info;
	objectSize = fh.GetOutputSize();
	objectMemSize = fh.GetMemorySize();
	
	nonCacheData = ( byte * ) soundCacheAllocator.Alloc( objectMemSize );
	fh.Read( nonCacheData, objectMemSize, NULL );
	
	// optionally convert it to 22kHz to save memory
	CheckForDownSample();
	
	// create hardware audio buffers
	if( idSoundSystemLocal::useOpenAL )
	{
		// PCM loads directly
		if( objectInfo.wFormatTag == WAVE_FORMAT_TAG_PCM )
		{
			alGetError();
			alGenBuffers( 1, &openalBuffer );
			
			if( alGetError() != AL_NO_ERROR )
			{
				common->Error( "idSoundCache: error generating OpenAL hardware buffer" );
			}
			
			if( alIsBuffer( openalBuffer ) )
			{
				alGetError();
				alBufferData( openalBuffer, objectInfo.nChannels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, nonCacheData, objectMemSize, objectInfo.nSamplesPerSec );
				
				if( alGetError() != AL_NO_ERROR )
				{
					common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" );
				}
				else
				{
					// removed the code here as it causes
					// micro stutter in the camera.
					hardwareBuffer = true;
				}
			}
		}
		
		// OGG decompressed at load time (when smaller than s_decompressionLimit seconds, 6 seconds by default)
		if( objectInfo.wFormatTag == WAVE_FORMAT_TAG_OGG )
		{
			if( ( alIsExtensionPresent( ID_ALCHAR "EAX-RAM" ) == AL_TRUE ) && ( objectSize < ( ( int ) objectInfo.nSamplesPerSec * idSoundSystemLocal::s_decompressionLimit.GetInteger() ) ) )
			{
				alGetError();
				alGenBuffers( 1, &openalBuffer );
				
				if( alGetError() != AL_NO_ERROR )
				{
					common->Error( "idSoundCache: error generating OpenAL hardware buffer" );
				}
				
				if( alIsBuffer( openalBuffer ) )
				{
					idSampleDecoder *decoder = idSampleDecoder::Alloc();
					float *destData = ( float * ) soundCacheAllocator.Alloc( ( LengthIn44kHzSamples() + 1 ) * sizeof( float ) );
					
					// Decoder *always* outputs 44 kHz data
					decoder->Decode( this, 0, LengthIn44kHzSamples(), destData );
					
					// Downsample back to original frequency (save memory)
					if( objectInfo.nSamplesPerSec == 11025 )
					{
						for( int i = 0; i < objectSize; i++ )
						{
							if( destData[i * 4] < -32768.0f )
							{
								( ( short * ) destData ) [i] = -32768;
							}
							else if( destData[i * 4] > 32767.0f )
							{
								( ( short * ) destData ) [i] = 32767;
							}
							else
							{
								( ( short * ) destData ) [i] = idMath::FtoiFast( destData[i * 4] );
							}
						}
					}
					else if( objectInfo.nSamplesPerSec == 22050 )
					{
						for( int i = 0; i < objectSize; i++ )
						{
							if( destData[i * 2] < -32768.0f )
							{
								( ( short * ) destData ) [i] = -32768;
							}
							else if( destData[i * 2] > 32767.0f )
							{
								( ( short * ) destData ) [i] = 32767;
							}
							else
							{
								( ( short * ) destData ) [i] = idMath::FtoiFast( destData[i * 2] );
							}
						}
					}
					else
					{
						for( int i = 0; i < objectSize; i++ )
						{
							if( destData[i] < -32768.0f )
							{
								( ( short * ) destData ) [i] = -32768;
							}
							else if( destData[i] > 32767.0f )
							{
								( ( short * ) destData ) [i] = 32767;
							}
							else
							{
								( ( short * ) destData ) [i] = idMath::FtoiFast( destData[i] );
							}
						}
					}
					alGetError();
					alBufferData( openalBuffer, objectInfo.nChannels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, destData, objectSize * sizeof( short ), objectInfo.nSamplesPerSec );
					
					if( alGetError() != AL_NO_ERROR )
					{
						common->Error( "idSoundCache: error loading data into OpenAL hardware buffer" );
					}
					else
					{
						// removed the code here as it causes
						// micro stutter in the camera.
						hardwareBuffer = true;
					}
					soundCacheAllocator.Free( ( byte * ) destData );
					idSampleDecoder::Free( decoder );
				}
			}
		}
		
		// Free memory if sample was loaded into hardware
		if( hardwareBuffer )
		{
			soundCacheAllocator.Free( nonCacheData );
			nonCacheData = NULL;
		}
	}
	fh.Close();
}