mirror of
https://github.com/w23/xash3d-fwgs
synced 2024-12-16 22:20:01 +01:00
5e0a0765ce
The `.editorconfig` file in this repo is configured to trim all trailing whitespace regardless of whether the line is modified. Trims all trailing whitespace in the repository to make the codebase easier to work with in editors that respect `.editorconfig`. `git blame` becomes less useful on these lines but it already isn't very useful. Commands: ``` find . -type f -name '*.h' -exec sed --in-place 's/[[:space:]]\+$//' {} \+ find . -type f -name '*.c' -exec sed --in-place 's/[[:space:]]\+$//' {} \+ ```
281 lines
6.0 KiB
C
281 lines
6.0 KiB
C
/*
|
|
snd_main.c - load & save various sound formats
|
|
Copyright (C) 2010 Uncle Mike
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "soundlib.h"
|
|
|
|
// global sound variables
|
|
sndlib_t sound;
|
|
|
|
void Sound_Reset( void )
|
|
{
|
|
// reset global variables
|
|
sound.width = sound.rate = 0;
|
|
sound.channels = sound.loopstart = 0;
|
|
sound.samples = sound.flags = 0;
|
|
sound.type = WF_UNKNOWN;
|
|
|
|
sound.wav = NULL;
|
|
sound.size = 0;
|
|
}
|
|
|
|
wavdata_t *SoundPack( void )
|
|
{
|
|
wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t ));
|
|
|
|
pack->buffer = sound.wav;
|
|
pack->width = sound.width;
|
|
pack->rate = sound.rate;
|
|
pack->type = sound.type;
|
|
pack->size = sound.size;
|
|
pack->loopStart = sound.loopstart;
|
|
pack->samples = sound.samples;
|
|
pack->channels = sound.channels;
|
|
pack->flags = sound.flags;
|
|
|
|
return pack;
|
|
}
|
|
|
|
/*
|
|
================
|
|
FS_LoadSound
|
|
|
|
loading and unpack to wav any known sound
|
|
================
|
|
*/
|
|
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
|
|
{
|
|
const char *ext = COM_FileExtension( filename );
|
|
string path, loadname;
|
|
qboolean anyformat = true;
|
|
fs_offset_t filesize = 0;
|
|
const loadwavfmt_t *format;
|
|
byte *f;
|
|
|
|
Sound_Reset(); // clear old sounddata
|
|
Q_strncpy( loadname, filename, sizeof( loadname ));
|
|
|
|
if( Q_stricmp( ext, "" ))
|
|
{
|
|
// we needs to compare file extension with list of supported formats
|
|
// and be sure what is real extension, not a filename with dot
|
|
for( format = sound.loadformats; format && format->formatstring; format++ )
|
|
{
|
|
if( !Q_stricmp( format->ext, ext ))
|
|
{
|
|
COM_StripExtension( loadname );
|
|
anyformat = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// special mode: skip any checks, load file from buffer
|
|
if( filename[0] == '#' && buffer && size )
|
|
goto load_internal;
|
|
|
|
// now try all the formats in the selected list
|
|
for( format = sound.loadformats; format && format->formatstring; format++)
|
|
{
|
|
if( anyformat || !Q_stricmp( ext, format->ext ))
|
|
{
|
|
Q_sprintf( path, format->formatstring, loadname, "", format->ext );
|
|
f = FS_LoadFile( path, &filesize, false );
|
|
if( f && filesize > 0 )
|
|
{
|
|
if( format->loadfunc( path, f, filesize ))
|
|
{
|
|
Mem_Free(f); // release buffer
|
|
return SoundPack(); // loaded
|
|
}
|
|
else Mem_Free(f); // release buffer
|
|
}
|
|
}
|
|
}
|
|
|
|
load_internal:
|
|
for( format = sound.loadformats; format && format->formatstring; format++ )
|
|
{
|
|
if( anyformat || !Q_stricmp( ext, format->ext ))
|
|
{
|
|
if( buffer && size > 0 )
|
|
{
|
|
if( format->loadfunc( loadname, buffer, size ))
|
|
return SoundPack(); // loaded
|
|
}
|
|
}
|
|
}
|
|
|
|
if( filename[0] != '#' )
|
|
Con_DPrintf( S_WARN "FS_LoadSound: couldn't load \"%s\"\n", loadname );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
================
|
|
Sound_FreeSound
|
|
|
|
free WAV buffer
|
|
================
|
|
*/
|
|
void FS_FreeSound( wavdata_t *pack )
|
|
{
|
|
if( !pack ) return;
|
|
if( pack->buffer ) Mem_Free( pack->buffer );
|
|
Mem_Free( pack );
|
|
}
|
|
|
|
/*
|
|
================
|
|
FS_OpenStream
|
|
|
|
open and reading basic info from sound stream
|
|
================
|
|
*/
|
|
stream_t *FS_OpenStream( const char *filename )
|
|
{
|
|
const char *ext = COM_FileExtension( filename );
|
|
string path, loadname;
|
|
qboolean anyformat = true;
|
|
const streamfmt_t *format;
|
|
stream_t *stream;
|
|
|
|
Sound_Reset(); // clear old streaminfo
|
|
Q_strncpy( loadname, filename, sizeof( loadname ));
|
|
|
|
if( Q_stricmp( ext, "" ))
|
|
{
|
|
// we needs to compare file extension with list of supported formats
|
|
// and be sure what is real extension, not a filename with dot
|
|
for( format = sound.streamformat; format && format->formatstring; format++ )
|
|
{
|
|
if( !Q_stricmp( format->ext, ext ))
|
|
{
|
|
COM_StripExtension( loadname );
|
|
anyformat = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// now try all the formats in the selected list
|
|
for( format = sound.streamformat; format && format->formatstring; format++)
|
|
{
|
|
if( anyformat || !Q_stricmp( ext, format->ext ))
|
|
{
|
|
Q_sprintf( path, format->formatstring, loadname, "", format->ext );
|
|
if(( stream = format->openfunc( path )) != NULL )
|
|
{
|
|
stream->format = format;
|
|
return stream; // done
|
|
}
|
|
}
|
|
}
|
|
|
|
Con_Reportf( "FS_OpenStream: couldn't open \"%s\"\n", loadname );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
================
|
|
FS_StreamInfo
|
|
|
|
get basic stream info
|
|
================
|
|
*/
|
|
wavdata_t *FS_StreamInfo( stream_t *stream )
|
|
{
|
|
static wavdata_t info;
|
|
|
|
if( !stream ) return NULL;
|
|
|
|
// fill structure
|
|
info.loopStart = -1;
|
|
info.rate = stream->rate;
|
|
info.width = stream->width;
|
|
info.channels = stream->channels;
|
|
info.flags = SOUND_STREAM;
|
|
info.size = stream->size;
|
|
info.buffer = NULL;
|
|
info.samples = 0; // not actual for streams
|
|
info.type = stream->type;
|
|
|
|
return &info;
|
|
}
|
|
|
|
/*
|
|
================
|
|
FS_ReadStream
|
|
|
|
extract stream as wav-data and put into buffer, move file pointer
|
|
================
|
|
*/
|
|
int FS_ReadStream( stream_t *stream, int bytes, void *buffer )
|
|
{
|
|
if( !stream || !stream->format || !stream->format->readfunc )
|
|
return 0;
|
|
|
|
if( bytes <= 0 || buffer == NULL )
|
|
return 0;
|
|
|
|
return stream->format->readfunc( stream, bytes, buffer );
|
|
}
|
|
|
|
/*
|
|
================
|
|
FS_GetStreamPos
|
|
|
|
get stream position (in bytes)
|
|
================
|
|
*/
|
|
int FS_GetStreamPos( stream_t *stream )
|
|
{
|
|
if( !stream || !stream->format || !stream->format->getposfunc )
|
|
return -1;
|
|
|
|
return stream->format->getposfunc( stream );
|
|
}
|
|
|
|
/*
|
|
================
|
|
FS_SetStreamPos
|
|
|
|
set stream position (in bytes)
|
|
================
|
|
*/
|
|
int FS_SetStreamPos( stream_t *stream, int newpos )
|
|
{
|
|
if( !stream || !stream->format || !stream->format->setposfunc )
|
|
return -1;
|
|
|
|
return stream->format->setposfunc( stream, newpos );
|
|
}
|
|
|
|
/*
|
|
================
|
|
FS_FreeStream
|
|
|
|
close sound stream
|
|
================
|
|
*/
|
|
void FS_FreeStream( stream_t *stream )
|
|
{
|
|
if( !stream || !stream->format || !stream->format->freefunc )
|
|
return;
|
|
|
|
stream->format->freefunc( stream );
|
|
}
|