/* Copyright (C) 2009 Id Software, Inc. Copyright (C) 2004 Michael Liebscher Copyright (C) 1997-2001 Id Software, Inc. 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 2 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "../wolfiphone.h" filehandle_t *fh; PRIVATE size_t ovc_read( void *ptr, size_t size, size_t nmemb, void *dataSource ) { if( ! size || ! nmemb ) { return 0; } return FS_ReadFile( ptr, size, nmemb, fh ); } PRIVATE int ovc_seek( void *dataSource, ogg_int64_t offset, int whence ) { return FS_FileSeek( fh, offset, whence ); } PRIVATE int ovc_close( void *dataSource ) { return 0; } PRIVATE long ovc_tell( void *dataSource ) { return FS_FileTell( fh ); } /* ----------------------------------------------------------------------------- Function: LoadOggInfo -Load ogg file. Parameters: filename -[in] Name of wav file to load. wav -[out] wav data. info -[out] wav sound info. Returns: True if file loaded, otherwise false. Notes: Caller is responsible for freeing wav data by calling Z_Free. ----------------------------------------------------------------------------- */ PUBLIC _boolean LoadOggInfo( const char *filename, W8 **wav, soundInfo_t *info ) { W8 *data; int size; int dummy; char *newFilename; int len; OggVorbis_File vorbisFile; vorbis_info vorbisInfo; ov_callbacks vorbisCallbacks = {ovc_read, ovc_seek, ovc_close, ovc_tell}; int ret; newFilename = strdup( filename ); len = strlen( newFilename ); if ( len < 5 || strcmp( newFilename + len - 4, ".wav" ) ) { free( newFilename ); return false; } newFilename[ len - 3 ] = 'o'; newFilename[ len - 2 ] = 'g'; newFilename[ len - 1 ] = 'g'; fh = FS_OpenFile( newFilename, 0 ); if( ! fh ) { free( newFilename ); return false; } if( (ret = ov_open_callbacks( fh, &vorbisFile, NULL, 0, vorbisCallbacks )) < 0 ) { free( newFilename ); return false; } vorbisInfo = *ov_info( &vorbisFile, -1 ); if( vorbisInfo.channels != 1 && vorbisInfo.channels != 2 ) { Com_Printf( "Only mono and stereo OGG files supported (%s)\n", newFilename ); free( newFilename ); return false; } info->channels = vorbisInfo.channels; info->sample_rate = vorbisInfo.rate; info->sample_size = 2; #define BUFFER_SIZE ( 128 * 1024 ) data = (W8 *)malloc( BUFFER_SIZE ); size = 0; while( size < BUFFER_SIZE ) { int read = 0; read = ov_read( &vorbisFile, (char *)data + size, BUFFER_SIZE - size, &dummy ); if( read == 0 ) { break; } if( read <= 0 ) { Com_Printf( "Only mono and stereo OGG files supported (%s)\n", newFilename ); free( newFilename ); return false; } size += read; } info->samples = size / ( info->channels * info->sample_size ); // Com_Printf("Loaded %s: channels=%d, sample_rate=%d, sample_size=%d, samples=%d. \n", newFilename, info->channels, info->sample_rate, info->sample_size, info->samples ); free( newFilename ); *wav = (W8 *)Z_Malloc( size ); memcpy(*wav, data, size ); free( data ); FS_CloseFile( fh ); return true; }