コード例 #1
0
ファイル: snd_decoder_wav.c プロジェクト: codetwister/qfusion
snd_stream_t *decoder_wav_open( const char *filename, qboolean *delay )
{
	snd_stream_t *stream;
	snd_wav_stream_t *wav_stream;

	stream = decoder_stream_init( &wav_decoder );
	if( !stream )
		return NULL;

	stream->isUrl = trap_FS_IsUrl( filename );
	if( stream->isUrl )
		return NULL;

	if( delay )
		*delay = qfalse;

	stream->ptr = S_Malloc( sizeof( snd_wav_stream_t ) );
	wav_stream = (snd_wav_stream_t *)stream->ptr;

	trap_FS_FOpenFile( filename, &wav_stream->filenum, FS_READ|FS_NOSIZE );
	if( !wav_stream->filenum )
	{
		decoder_wav_stream_shutdown( stream );
		return NULL;
	}

	if( !decoder_wav_cont_open( stream ) )
	{
		return NULL;
	}

	return stream;
}
コード例 #2
0
ファイル: snd_music.c プロジェクト: Picmip/qfusion
/*
* S_AllocTrack
*/
static bgTrack_t *S_AllocTrack( const char *filename ) {
	bgTrack_t *track;

	track = S_Malloc( sizeof( *track ) + strlen( filename ) + 1 );
	track->ignore = false;
	track->filename = (char *)( (uint8_t *)track + sizeof( *track ) );
	strcpy( track->filename, filename );
	track->isUrl = trap_FS_IsUrl( track->filename );
	track->muteOnPause = track->isUrl;
	track->anext = s_bgTrackHead;
	s_bgTrackHead = track;

	return track;
}
コード例 #3
0
/*
* S_AllocTrack
*/
static bgTrack_t *S_AllocTrack( const char *filename )
{
    bgTrack_t *track;

    track = S_Malloc( sizeof( *track ) + strlen( filename ) + 1 );
    track->stream = NULL;
    track->ignore = qfalse;
    track->filename = (char *)((qbyte *)track + sizeof( *track ));
    strcpy( track->filename, filename );
    track->isUrl = trap_FS_IsUrl( filename );
    track->anext = s_bgTrackHead;
    s_bgTrackHead = track;

    return track;
}
コード例 #4
0
ファイル: snd_main.c プロジェクト: cfr/qfusion
/*
* SF_FindName
*/
static sfx_t *SF_FindName( const char *name )
{
	int i;
	sfx_t *sfx;

	if( !name )
		S_Error( "SF_FindName: NULL" );
	if( !name[0] != '\0' )
	{
		assert( name[0] != '\0' );
		S_Error( "SF_FindName: empty name" );
	}

	if( strlen( name ) >= MAX_QPATH )
		S_Error( "Sound name too long: %s", name );

	// see if already loaded
	for( i = 0; i < num_sfx; i++ )
	{
		if( !strcmp( known_sfx[i].name, name ) )
			return &known_sfx[i];
	}

	// find a free sfx
	for( i = 0; i < num_sfx; i++ )
	{
		if( !known_sfx[i].name[0] )
			break;
	}

	if( i == num_sfx )
	{
		if( num_sfx == MAX_SFX )
			S_Error( "S_FindName: out of sfx_t" );
		num_sfx++;
	}

	sfx = &known_sfx[i];
	memset( sfx, 0, sizeof( *sfx ) );
	Q_strncpyz( sfx->name, name, sizeof( sfx->name ) );
	sfx->isUrl = trap_FS_IsUrl( name );

	return sfx;
}
コード例 #5
0
ファイル: snd_decoder_ogg.c プロジェクト: codetwister/qfusion
snd_stream_t *decoder_ogg_open( const char *filename, qboolean *delay )
{
	snd_stream_t *stream;
	snd_ogg_stream_t *ogg_stream;

	// Open
	stream = decoder_stream_init( &ogg_decoder );
	if( !stream )
	{
		Com_Printf( "Error initializing .ogg stream: %s\n", filename );
		return NULL;
	}

	stream->isUrl = trap_FS_IsUrl( filename );
	stream->ptr = S_Malloc( sizeof( snd_ogg_stream_t ) );
	ogg_stream = (snd_ogg_stream_t *)stream->ptr;

	trap_FS_FOpenFile( filename, &ogg_stream->filenum, FS_READ|FS_NOSIZE );
	if( !ogg_stream->filenum )
	{
		decoder_ogg_stream_shutdown( stream );
		return NULL;
	}

	if( delay )
		*delay = qfalse;

	if( stream->isUrl && delay )
	{
		*delay = qtrue;
		return stream;
	}

	if( !decoder_ogg_cont_open( stream ) )
	{
		decoder_ogg_close( stream );
		return NULL;
	}

	return stream;
}
コード例 #6
0
ファイル: snd_decoder_wav.c プロジェクト: codetwister/qfusion
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;
}
コード例 #7
0
ファイル: snd_music.c プロジェクト: Clever-Boy/qfusion
/*
* 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;
}
コード例 #8
0
ファイル: snd_decoder_ogg.c プロジェクト: codetwister/qfusion
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;
}
コード例 #9
0
ファイル: snd_buffers.c プロジェクト: Clever-Boy/qfusion
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;
}