Beispiel #1
0
/*
* S_HandlePositionedRawSamplesCmd
*/
static unsigned S_HandlePositionedRawSamplesCmd( const sndPositionedRawSamplesCmd_t *cmd )
{
	S_PositionedRawSamples( cmd->entnum, cmd->fvol, cmd->attenuation,
		cmd->samples, cmd->rate, cmd->width, cmd->channels, cmd->data );
	S_Free( ( void * )cmd->data );
	return sizeof( *cmd );
}
Beispiel #2
0
void S_StopBackgroundTrack( void )
{
    bgTrack_t *next;

    if( source )
        qalSourceStop( source );

    if( alloced_buffers ) {
        qalSourceUnqueueBuffers( source, MUSIC_BUFFERS, buffers );
        qalDeleteBuffers( MUSIC_BUFFERS, buffers );
        alloced_buffers = queued_buffers = qfalse;
    }

    music_source_free();

    qalGetError();

    while( s_bgTrackHead )
    {
        next = s_bgTrackHead->anext;

        S_CloseMusicTrack( s_bgTrackHead );
        S_Free( s_bgTrackHead );

        s_bgTrackHead = next;
    }

    s_bgTrack = NULL;
    s_bgTrackHead = NULL;

    s_bgTrackBuffering = qfalse;

    s_bgTrackPaused = qfalse;
}
Beispiel #3
0
/*
* S_HandleRawSamplesCmd
*/
static unsigned S_HandleRawSamplesCmd( const sndRawSamplesCmd_t *cmd )
{
	S_RawSamples( cmd->samples, cmd->rate, cmd->width, cmd->channels,
		cmd->data, cmd->music );
	S_Free( ( void * )cmd->data );
	return sizeof( *cmd );
}
Beispiel #4
0
void S_ShutdownDecoders( qboolean verbose )
{
	S_Free( extensionlist );
	extensionlist = NULL;
	extensionlist_size = 0;

	decoders = NULL;
	SNDOGG_Shutdown( verbose );
}
Beispiel #5
0
static void decoder_register( snd_decoder_t *decoder )
{
	decoder->next = decoders;
	decoders = decoder;

	if( extensionlist_size - strlen( extensionlist ) - 1 < strlen( decoder->ext ) + 1 )
	{
		char *oldlist = extensionlist;
		extensionlist_size = max( extensionlist_size * 2, (int)( strlen( extensionlist ) + strlen( decoder->ext ) + 1 + 1 ) );
		extensionlist = S_Malloc( extensionlist_size );
		Q_strncpyz( extensionlist, oldlist, extensionlist_size );
		S_Free( oldlist );
	}
	Q_strncatz( extensionlist, " ", extensionlist_size );
	Q_strncatz( extensionlist, decoder->ext, extensionlist_size );
}
Beispiel #6
0
void * stereo_mono( void *data, snd_info_t *info )
{
	int i, interleave, gain;
	void *outdata;

	outdata = S_Malloc( info->samples * info->width );
	interleave = info->channels * info->width;
	gain = s_stereo2mono->integer;
	clamp( gain, -1, 1 );

	if( info->width == 2 )
	{
		short *pin, *pout;

		pin = (short*)data;
		pout = (short*)outdata;

		for( i = 0; i < info->size; i += interleave, pin += info->channels, pout++ )
		{
			*pout = ((1-gain) * pin[0] + (1+gain) * pin[1]) / 2;
		}
	}
	else if( info->width == 1 )
	{
		char *pin, *pout;

		pin = (char*)data;
		pout = (char*)outdata;

		for( i = 0; i < info->size; i += interleave, pin += info->channels, pout++ )
		{
			*pout = ((1-gain) * pin[0] + (1+gain) * pin[1]) / 2;
		}
	}
	else
	{
		S_Free( outdata );
		return NULL;
	}

	info->channels = 1;
	info->size = info->samples * info->width;

	return outdata;
}
Beispiel #7
0
/*
* SF_FreeSounds
*/
void SF_FreeSounds( void )
{
	int i;
	sfx_t *sfx;

	// wait for the queue to be processed
	S_FinishSoundCmdPipe( s_cmdPipe );

	// free all sounds
	for( i = 0, sfx = known_sfx; i < num_sfx; i++, sfx++ )
	{
		if( !sfx->name[0] ) {
			continue;
		}
		S_Free( sfx->cache );
		memset( sfx, 0, sizeof( *sfx ) );
	}
}
Beispiel #8
0
/*
* S_StopBackgroundTrack
*/
void S_StopBackgroundTrack( void ) {
	bgTrack_t *next;

	S_CloseBackgroundTrackTask();

	while( s_bgTrackHead ) {
		next = s_bgTrackHead->anext;

		S_CloseMusicTrack( s_bgTrackHead );
		S_Free( s_bgTrackHead );

		s_bgTrackHead = next;
	}

	s_bgTrack = NULL;
	s_bgTrackHead = NULL;

	s_bgTrackMuted = false;
	s_bgTrackPaused = false;
}
Beispiel #9
0
/*
* S_ShutdownSources
*/
void S_ShutdownSources( void )
{
	int i;

	if( !src_inited )
		return;

	// Destroy all the sources
	for( i = 0; i < src_count; i++ )
	{
		qalSourceStop( srclist[i].source );
		qalDeleteSources( 1, &srclist[i].source );
	}

	memset( srclist, 0, sizeof( srclist ) );

	S_Free( entlist );
	entlist = NULL;

	src_inited = qfalse;
}
Beispiel #10
0
/*
* SF_EndRegistration
*/
void SF_EndRegistration( void )
{
	int i;
	sfx_t *sfx;

	// wait for the queue to be processed
	S_FinishSoundCmdPipe( s_cmdPipe );

	s_registering = false;

	// free any sounds not from this registration sequence
	for( i = 0, sfx = known_sfx; i < num_sfx; i++, sfx++ ) {
		if( !sfx->name[0] ) {
			continue;
		}
		if( sfx->registration_sequence != s_registration_sequence ) {
			// we don't need this sound
			S_Free( sfx->cache );
			memset( sfx, 0, sizeof( *sfx ) );
		}
	}
}
Beispiel #11
0
void *decoder_wav_load( const char *filename, snd_info_t *info )
{
	int filenum;
	int read;
	void *buffer;

	if( trap_FS_IsUrl( filename ) )
		return NULL;

	trap_FS_FOpenFile( filename, &filenum, FS_READ|FS_NOSIZE );
	if( !filenum )
		return NULL;

	if( !read_wav_header( filenum, info ) )
	{
		trap_FS_FCloseFile( filenum );
		Com_Printf( "Can't understand .wav file: %s\n", filename );
		return NULL;
	}

	buffer = S_Malloc( info->size );
	read = trap_FS_Read( buffer, info->size, filenum );
	if( read != info->size )
	{
		S_Free( buffer );
		trap_FS_FCloseFile( filenum );
		Com_Printf( "Error reading .wav file: %s\n", filename );
		return NULL;
	}

	byteSwapRawSamples( info->samples, info->width, info->channels, (qbyte *)buffer );

	trap_FS_FCloseFile( filenum );

	return buffer;
}
Beispiel #12
0
/*
* S_ReadPlaylistFile
*/
static bgTrack_t *S_ReadPlaylistFile( const char *filename, bool shuffle, bool loop )
{
	int filenum, length;
	char *tmpname = 0;
	size_t tmpname_size = 0;
	char *data, *line, *entry;
	playlistItem_t items[MAX_PLAYLIST_ITEMS];
	int i, numItems = 0;

	length = trap_FS_FOpenFile( filename, &filenum, FS_READ );
	if( length < 0 )
		return NULL;

	// load the playlist into memory
	data = S_Malloc( length + 1 );
	trap_FS_Read( data, length, filenum );
	trap_FS_FCloseFile( filenum );

	srand( time( NULL ) );

	while( *data )
	{
		size_t s;

		entry = data;

		// read the whole line
		for( line = data; *line != '\0' && *line != '\n'; line++ );

		// continue reading from the next character, if possible
		data = (*line == '\0' ? line : line + 1);

		*line = '\0';

		// trim whitespaces, tabs, etc
		entry = Q_trim( entry );

		// special M3U entry or comment
		if( !*entry || *entry == '#' )
			continue;

		if( trap_FS_IsUrl( entry ) )
		{
			items[numItems].track = S_AllocTrack( entry );
		}
		else
		{
			// append the entry name to playlist path
			s = strlen( filename ) + 1 + strlen( entry ) + 1;
			if( s > tmpname_size )
			{
				if( tmpname )
					S_Free( tmpname );
				tmpname_size = s;
				tmpname = S_Malloc( tmpname_size );
			}

			Q_strncpyz( tmpname, filename, tmpname_size );
			COM_StripFilename( tmpname );
			Q_strncatz( tmpname, "/", tmpname_size );
			Q_strncatz( tmpname, entry, tmpname_size );
			COM_SanitizeFilePath( tmpname );

			items[numItems].track = S_AllocTrack( tmpname );
		}

		if( ++numItems == MAX_PLAYLIST_ITEMS )
			break;
	}

	if( tmpname )
	{
		S_Free( tmpname );
		tmpname = NULL;
	}

	if( !numItems )
		return NULL;

	// set the playing order
	for( i = 0; i < numItems; i++ )
		items[i].order = (shuffle ? (rand() % numItems) : i);

	// sort the playlist
	R_SortPlaylistItems( numItems, items );

	// link the playlist
	for( i = 1; i < numItems; i++ )
	{
		items[i-1].track->next = items[i].track;
		items[i].track->prev = items[i-1].track;
		items[i].track->loop = loop;
	}
	items[numItems-1].track->next = items[0].track;
	items[0].track->prev = items[numItems-1].track;
	items[0].track->loop = loop;

	return items[0].track;
}
Beispiel #13
0
void *decoder_ogg_load( const char *filename, snd_info_t *info )
{
	OggVorbis_File vorbisfile;
	int filenum, bitstream, bytes_read, bytes_read_total;
	char *buffer;
	ov_callbacks callbacks = { ovcb_read, ovcb_seek, ovcb_close, ovcb_tell };

	trap_FS_FOpenFile( filename, &filenum, FS_READ|FS_NOSIZE );
	if( !filenum )
		return NULL;

	if( trap_FS_IsUrl( filename ) )
	{
		callbacks.seek_func = NULL;
		callbacks.tell_func = NULL;
	}

	qov_open_callbacks( (void *) (qintptr) filenum, &vorbisfile, NULL, 0, callbacks );

	if( callbacks.seek_func && !qov_seekable( &vorbisfile ) )
	{
		Com_Printf( "Error unsupported .ogg file (not seekable): %s\n", filename );
		qov_clear( &vorbisfile ); // Does FS_FCloseFile
		return NULL;
	}

	if( qov_streams( &vorbisfile ) != 1 )
	{
		Com_Printf( "Error unsupported .ogg file (multiple logical bitstreams): %s\n", filename );
		qov_clear( &vorbisfile ); // Does FS_FCloseFile
		return NULL;
	}

	if( !read_ogg_header( vorbisfile, info ) )
	{
		Com_Printf( "Error reading .ogg file header: %s\n", filename );
		qov_clear( &vorbisfile ); // Does FS_FCloseFile
		return NULL;
	}

	buffer = S_Malloc( info->size );

	bytes_read_total = 0;
	do
	{
#ifdef ENDIAN_BIG
		bytes_read = qov_read( &vorbisfile, buffer+bytes_read_total, info->size-bytes_read_total, 1, 2, 1, &bitstream );
#elif defined (ENDIAN_LITTLE)
		bytes_read = qov_read( &vorbisfile, buffer+bytes_read_total, info->size-bytes_read_total, 0, 2, 1, &bitstream );
#else
#error "runtime endianess detection support missing"
#endif
		bytes_read_total += bytes_read;
	}
	while( bytes_read > 0 && bytes_read_total < info->size );

	qov_clear( &vorbisfile ); // Does FS_FCloseFile
	if( !bytes_read_total )
	{
		Com_Printf( "Error reading .ogg file: %s\n", filename );
		S_Free( buffer );
		return NULL;
	}

	return buffer;
}
Beispiel #14
0
static void decoder_ogg_stream_shutdown( snd_stream_t *stream )
{
	S_Free( stream->ptr );
	decoder_stream_shutdown( stream );
}
Beispiel #15
0
void decoder_stream_shutdown( snd_stream_t *stream )
{
	S_Free( stream );
}
Beispiel #16
0
bool S_LoadBuffer( sfx_t *sfx )
{
	ALenum error;
	void *data;
	snd_info_t info;
	ALuint format;

	if( !sfx ) {
		return false;
	}
	if( sfx->filename[0] == '\0' || sfx->inMemory )
		return false;
	if( trap_FS_IsUrl( sfx->filename ) )
		return false;

	data = S_LoadSound( sfx->filename, &info );
	if( !data )
	{
		//Com_DPrintf( "Couldn't load %s\n", sfx->filename );
		return false;
	}

	if( info.channels > 1 )
	{
		void *temp = stereo_mono( data, &info );
		if( temp )
		{
			S_Free( data );
			data = temp;
		}
	}

	format = S_SoundFormat( info.width, info.channels );

	qalGenBuffers( 1, &sfx->buffer );
	if( ( error = qalGetError() ) != AL_NO_ERROR )
	{
		S_Free( data );
		Com_Printf( "Couldn't create a sound buffer for %s (%s)\n", sfx->filename, S_ErrorMessage( error ) );
		return false;
	}

	qalBufferData( sfx->buffer, format, data, info.size, info.rate );
	error = qalGetError();

	// If we ran out of memory, start evicting the least recently used sounds
	while( error == AL_OUT_OF_MEMORY )
	{
		if( !buffer_evict() )
		{
			S_Free( data );
			Com_Printf( "Out of memory loading %s\n", sfx->filename );
			return false;
		}

		// Try load it again
		qalGetError();
		qalBufferData( sfx->buffer, format, data, info.size, info.rate );
		error = qalGetError();
	}

	// Some other error condition
	if( error != AL_NO_ERROR )
	{
		S_Free( data );
		Com_Printf( "Couldn't fill sound buffer for %s (%s)", sfx->filename, S_ErrorMessage( error ) );
		return false;
	}

	S_Free( data );
	sfx->inMemory = true;

	return true;
}