2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
2012-11-28 15:47:07 +00:00
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2012-11-26 18:58:24 +00:00
2012-11-28 15:47:07 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
2012-11-26 18:58:24 +00:00
Doom 3 BFG Edition Source Code 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 .
Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# pragma hdrstop
2012-12-22 15:18:19 +00:00
# include "precompiled.h"
2012-11-26 18:58:24 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Contains the WaveFile implementation .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# include "WaveFile.h"
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : Open
2012-11-28 15:47:07 +00:00
Returns true if the Open was successful and the file matches the expected format . If this
2012-11-26 18:58:24 +00:00
returns false , there is no need to call Close .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWaveFile : : Open ( const char * filename )
{
2012-11-26 18:58:24 +00:00
Close ( ) ;
2012-11-28 15:47:07 +00:00
if ( filename = = NULL | | filename [ 0 ] = = 0 )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
if ( file = = NULL )
{
2012-11-26 18:58:24 +00:00
file = fileSystem - > OpenFileReadMemory ( filename ) ;
2012-11-28 15:47:07 +00:00
if ( file = = NULL )
{
2012-11-26 18:58:24 +00:00
return false ;
}
}
2012-11-28 15:47:07 +00:00
if ( file - > Length ( ) = = 0 )
{
2012-11-26 18:58:24 +00:00
Close ( ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
struct header_t
{
2012-11-26 18:58:24 +00:00
uint32 id ;
uint32 size ;
uint32 format ;
} header ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
file - > Read ( & header , sizeof ( header ) ) ;
idSwap : : Big ( header . id ) ;
idSwap : : Little ( header . size ) ;
idSwap : : Big ( header . format ) ;
2012-11-28 15:47:07 +00:00
if ( header . id ! = ' RIFF ' | | header . format ! = ' WAVE ' | | header . size < 4 )
{
2012-11-26 18:58:24 +00:00
Close ( ) ;
idLib : : Warning ( " Header is not RIFF WAVE in %s " , filename ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
uint32 riffSize = header . size + 8 ;
uint32 offset = sizeof ( header ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
// Scan the file collecting chunks
2012-11-28 15:47:07 +00:00
while ( offset < riffSize )
{
struct chuckHeader_t
{
2012-11-26 18:58:24 +00:00
uint32 id ;
uint32 size ;
} chunkHeader ;
2012-11-28 15:47:07 +00:00
if ( file - > Read ( & chunkHeader , sizeof ( chunkHeader ) ) ! = sizeof ( chunkHeader ) )
{
2012-11-26 18:58:24 +00:00
// It seems like some tools have extra data after the last chunk for no apparent reason
// so don't treat this as an error
return true ;
}
idSwap : : Big ( chunkHeader . id ) ;
idSwap : : Little ( chunkHeader . size ) ;
offset + = sizeof ( chunkHeader ) ;
2012-11-28 15:47:07 +00:00
if ( chunks . Num ( ) > = chunks . Max ( ) )
{
2012-11-26 18:58:24 +00:00
Close ( ) ;
idLib : : Warning ( " More than %d chunks in %s " , chunks . Max ( ) , filename ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
chunk_t * chunk = chunks . Alloc ( ) ;
2012-11-26 18:58:24 +00:00
chunk - > id = chunkHeader . id ;
chunk - > size = chunkHeader . size ;
chunk - > offset = offset ;
offset + = chunk - > size ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
file - > Seek ( offset , FS_SEEK_SET ) ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : SeekToChunk
Seeks to the specified chunk and returns the size of the chunk or 0 if the chunk wasn ' t found .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
uint32 idWaveFile : : SeekToChunk ( uint32 id )
{
for ( int i = 0 ; i < chunks . Num ( ) ; i + + )
{
if ( chunks [ i ] . id = = id )
{
2012-11-26 18:58:24 +00:00
file - > Seek ( chunks [ i ] . offset , FS_SEEK_SET ) ;
return chunks [ i ] . size ;
}
}
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : GetChunkOffset
Seeks to the specified chunk and returns the size of the chunk or 0 if the chunk wasn ' t found .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
uint32 idWaveFile : : GetChunkOffset ( uint32 id )
{
for ( int i = 0 ; i < chunks . Num ( ) ; i + + )
{
if ( chunks [ i ] . id = = id )
{
2012-11-26 18:58:24 +00:00
return chunks [ i ] . offset ;
}
}
return 0 ;
}
// Used in XMA2WAVEFORMAT for per-stream data
2012-11-28 15:47:07 +00:00
typedef struct XMA2STREAMFORMAT
{
byte Channels ; // Number of channels in the stream (1 or 2)
byte RESERVED ; // Reserved for future use
uint16 ChannelMask ; // Spatial positions of the channels in the stream
2012-11-26 18:58:24 +00:00
} XMA2STREAMFORMAT ;
// Legacy XMA2 format structure (big-endian byte ordering)
2012-11-28 15:47:07 +00:00
typedef struct XMA2WAVEFORMAT
{
byte Version ; // XMA encoder version that generated the file.
// Always 3 or higher for XMA2 files.
byte NumStreams ; // Number of interleaved audio streams
byte RESERVED ; // Reserved for future use
byte LoopCount ; // Number of loop repetitions; 255 = infinite
uint32 LoopBegin ; // Loop begin point, in samples
uint32 LoopEnd ; // Loop end point, in samples
uint32 SampleRate ; // The file's decoded sample rate
uint32 EncodeOptions ; // Options for the XMA encoder/decoder
uint32 PsuedoBytesPerSec ; // Used internally by the XMA encoder
uint32 BlockSizeInBytes ; // Size in bytes of this file's XMA blocks (except
// possibly the last one). Always a multiple of
// 2Kb, since XMA blocks are arrays of 2Kb packets.
uint32 SamplesEncoded ; // Total number of PCM samples encoded in this file
uint32 SamplesInSource ; // Actual number of PCM samples in the source
// material used to generate this file
uint32 BlockCount ; // Number of XMA blocks in this file (and hence
// also the number of entries in its seek table)
2012-11-26 18:58:24 +00:00
} XMA2WAVEFORMAT ;
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : ReadWaveFormat
Reads a wave format header , returns NULL if it found one and read it .
otherwise , returns a human - readable error message .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
const char * idWaveFile : : ReadWaveFormat ( waveFmt_t & format )
{
2012-11-26 18:58:24 +00:00
memset ( & format , 0 , sizeof ( format ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
uint32 formatSize = SeekToChunk ( waveFmt_t : : id ) ;
2012-11-28 15:47:07 +00:00
if ( formatSize = = 0 )
{
2012-11-26 18:58:24 +00:00
return " No format chunk " ;
}
2012-11-28 15:47:07 +00:00
if ( formatSize < sizeof ( format . basic ) )
{
2012-11-26 18:58:24 +00:00
return " Format chunk too small " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
Read ( & format . basic , sizeof ( format . basic ) ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
idSwapClass < waveFmt_t : : basic_t > swap ;
swap . Little ( format . basic . formatTag ) ;
swap . Little ( format . basic . numChannels ) ;
swap . Little ( format . basic . samplesPerSec ) ;
swap . Little ( format . basic . avgBytesPerSec ) ;
swap . Little ( format . basic . blockSize ) ;
swap . Little ( format . basic . bitsPerSample ) ;
2012-11-28 15:47:07 +00:00
if ( format . basic . formatTag = = FORMAT_PCM )
{
}
else if ( format . basic . formatTag = = FORMAT_ADPCM )
{
2012-11-26 18:58:24 +00:00
Read ( & format . extraSize , sizeof ( format . extraSize ) ) ;
idSwap : : Little ( format . extraSize ) ;
2012-11-28 15:47:07 +00:00
if ( format . extraSize ! = sizeof ( waveFmt_t : : extra_t : : adpcm_t ) )
{
2012-11-26 18:58:24 +00:00
return " Incorrect number of coefficients in ADPCM file " ;
}
Read ( & format . extra . adpcm , sizeof ( format . extra . adpcm ) ) ;
idSwapClass < waveFmt_t : : extra_t : : adpcm_t > swap ;
swap . Little ( format . extra . adpcm . samplesPerBlock ) ;
swap . Little ( format . extra . adpcm . numCoef ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < format . extra . adpcm . numCoef ; i + + )
{
2012-11-26 18:58:24 +00:00
swap . Little ( format . extra . adpcm . aCoef [ i ] . coef1 ) ;
swap . Little ( format . extra . adpcm . aCoef [ i ] . coef2 ) ;
}
2012-11-28 15:47:07 +00:00
}
else if ( format . basic . formatTag = = FORMAT_XMA2 )
{
2012-11-26 18:58:24 +00:00
Read ( & format . extraSize , sizeof ( format . extraSize ) ) ;
idSwap : : Little ( format . extraSize ) ;
2012-11-28 15:47:07 +00:00
if ( format . extraSize ! = sizeof ( waveFmt_t : : extra_t : : xma2_t ) )
{
2012-11-26 18:58:24 +00:00
return " Incorrect chunk size in XMA2 file " ;
}
Read ( & format . extra . xma2 , sizeof ( format . extra . xma2 ) ) ;
idSwapClass < waveFmt_t : : extra_t : : xma2_t > swap ;
swap . Little ( format . extra . xma2 . numStreams ) ;
swap . Little ( format . extra . xma2 . channelMask ) ;
swap . Little ( format . extra . xma2 . samplesEncoded ) ;
swap . Little ( format . extra . xma2 . bytesPerBlock ) ;
swap . Little ( format . extra . xma2 . playBegin ) ;
swap . Little ( format . extra . xma2 . playLength ) ;
swap . Little ( format . extra . xma2 . loopBegin ) ;
swap . Little ( format . extra . xma2 . loopLength ) ;
swap . Little ( format . extra . xma2 . loopCount ) ;
swap . Little ( format . extra . xma2 . encoderVersion ) ;
swap . Little ( format . extra . xma2 . blockCount ) ;
2012-11-28 15:47:07 +00:00
}
else if ( format . basic . formatTag = = FORMAT_EXTENSIBLE )
{
2012-11-26 18:58:24 +00:00
Read ( & format . extraSize , sizeof ( format . extraSize ) ) ;
idSwap : : Little ( format . extraSize ) ;
2012-11-28 15:47:07 +00:00
if ( format . extraSize ! = sizeof ( waveFmt_t : : extra_t : : extensible_t ) )
{
2012-11-26 18:58:24 +00:00
return " Incorrect chunk size in extensible wave file " ;
}
Read ( & format . extra . extensible , sizeof ( format . extra . extensible ) ) ;
idSwapClass < waveFmt_t : : extra_t : : extensible_t > swap ;
swap . Little ( format . extra . extensible . validBitsPerSample ) ;
swap . Little ( format . extra . extensible . channelMask ) ;
swap . Little ( format . extra . extensible . subFormat . data1 ) ;
swap . Little ( format . extra . extensible . subFormat . data2 ) ;
swap . Little ( format . extra . extensible . subFormat . data3 ) ;
swap . Little ( format . extra . extensible . subFormat . data4 ) ;
swap . LittleArray ( format . extra . extensible . subFormat . data5 , 6 ) ;
2012-11-28 15:47:07 +00:00
waveFmt_t : : extra_t : : extensible_t : : guid_t pcmGuid =
{
2012-11-26 18:58:24 +00:00
FORMAT_PCM ,
0x0000 ,
0x0010 ,
0x8000 ,
{ 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 }
} ;
2012-11-28 15:47:07 +00:00
if ( memcmp ( & pcmGuid , & format . extra . extensible . subFormat , sizeof ( pcmGuid ) ) ! = 0 )
{
2012-11-26 18:58:24 +00:00
return " Unsupported Extensible format " ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return " Unknown wave format tag " ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return NULL ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : ReadWaveFormatDirect
2012-11-28 15:47:07 +00:00
Reads a wave format header from a file ptr ,
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWaveFile : : ReadWaveFormatDirect ( waveFmt_t & format , idFile * file )
{
2012-11-26 18:58:24 +00:00
file - > Read ( & format . basic , sizeof ( format . basic ) ) ;
idSwapClass < waveFmt_t : : basic_t > swap ;
swap . Little ( format . basic . formatTag ) ;
swap . Little ( format . basic . numChannels ) ;
swap . Little ( format . basic . samplesPerSec ) ;
swap . Little ( format . basic . avgBytesPerSec ) ;
swap . Little ( format . basic . blockSize ) ;
swap . Little ( format . basic . bitsPerSample ) ;
2012-11-28 15:47:07 +00:00
if ( format . basic . formatTag = = FORMAT_PCM )
{
}
else if ( format . basic . formatTag = = FORMAT_ADPCM )
{
2012-11-26 18:58:24 +00:00
file - > Read ( & format . extraSize , sizeof ( format . extraSize ) ) ;
idSwap : : Little ( format . extraSize ) ;
2012-11-28 15:47:07 +00:00
if ( format . extraSize ! = sizeof ( waveFmt_t : : extra_t : : adpcm_t ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
file - > Read ( & format . extra . adpcm , sizeof ( format . extra . adpcm ) ) ;
idSwapClass < waveFmt_t : : extra_t : : adpcm_t > swap ;
swap . Little ( format . extra . adpcm . samplesPerBlock ) ;
swap . Little ( format . extra . adpcm . numCoef ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < format . extra . adpcm . numCoef ; i + + )
{
2012-11-26 18:58:24 +00:00
swap . Little ( format . extra . adpcm . aCoef [ i ] . coef1 ) ;
swap . Little ( format . extra . adpcm . aCoef [ i ] . coef2 ) ;
}
2012-11-28 15:47:07 +00:00
}
else if ( format . basic . formatTag = = FORMAT_XMA2 )
{
2012-11-26 18:58:24 +00:00
file - > Read ( & format . extraSize , sizeof ( format . extraSize ) ) ;
idSwap : : Little ( format . extraSize ) ;
2012-11-28 15:47:07 +00:00
if ( format . extraSize ! = sizeof ( waveFmt_t : : extra_t : : xma2_t ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
file - > Read ( & format . extra . xma2 , sizeof ( format . extra . xma2 ) ) ;
idSwapClass < waveFmt_t : : extra_t : : xma2_t > swap ;
swap . Little ( format . extra . xma2 . numStreams ) ;
swap . Little ( format . extra . xma2 . channelMask ) ;
swap . Little ( format . extra . xma2 . samplesEncoded ) ;
swap . Little ( format . extra . xma2 . bytesPerBlock ) ;
swap . Little ( format . extra . xma2 . playBegin ) ;
swap . Little ( format . extra . xma2 . playLength ) ;
swap . Little ( format . extra . xma2 . loopBegin ) ;
swap . Little ( format . extra . xma2 . loopLength ) ;
swap . Little ( format . extra . xma2 . loopCount ) ;
swap . Little ( format . extra . xma2 . encoderVersion ) ;
swap . Little ( format . extra . xma2 . blockCount ) ;
2012-11-28 15:47:07 +00:00
}
else if ( format . basic . formatTag = = FORMAT_EXTENSIBLE )
{
2012-11-26 18:58:24 +00:00
file - > Read ( & format . extraSize , sizeof ( format . extraSize ) ) ;
idSwap : : Little ( format . extraSize ) ;
2012-11-28 15:47:07 +00:00
if ( format . extraSize ! = sizeof ( waveFmt_t : : extra_t : : extensible_t ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
file - > Read ( & format . extra . extensible , sizeof ( format . extra . extensible ) ) ;
idSwapClass < waveFmt_t : : extra_t : : extensible_t > swap ;
swap . Little ( format . extra . extensible . validBitsPerSample ) ;
swap . Little ( format . extra . extensible . channelMask ) ;
swap . Little ( format . extra . extensible . subFormat . data1 ) ;
swap . Little ( format . extra . extensible . subFormat . data2 ) ;
swap . Little ( format . extra . extensible . subFormat . data3 ) ;
swap . Little ( format . extra . extensible . subFormat . data4 ) ;
swap . LittleArray ( format . extra . extensible . subFormat . data5 , 6 ) ;
2012-11-28 15:47:07 +00:00
waveFmt_t : : extra_t : : extensible_t : : guid_t pcmGuid =
{
2012-11-26 18:58:24 +00:00
FORMAT_PCM ,
0x0000 ,
0x0010 ,
0x8000 ,
{ 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 }
} ;
2012-11-28 15:47:07 +00:00
if ( memcmp ( & pcmGuid , & format . extra . extensible . subFormat , sizeof ( pcmGuid ) ) ! = 0 )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : WriteWaveFormatDirect
2012-11-28 15:47:07 +00:00
Writes a wave format header to a file ptr ,
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWaveFile : : WriteWaveFormatDirect ( waveFmt_t & format , idFile * file )
{
2012-11-26 18:58:24 +00:00
//idSwapClass<waveFmt_t::basic_t> swap;
//swap.Little( format.basic.formatTag );
//swap.Little( format.basic.numChannels );
//swap.Little( format.basic.samplesPerSec );
//swap.Little( format.basic.avgBytesPerSec );
//swap.Little( format.basic.blockSize );
//swap.Little( format.basic.bitsPerSample );
file - > Write ( & format . basic , sizeof ( format . basic ) ) ;
2012-11-28 15:47:07 +00:00
if ( format . basic . formatTag = = FORMAT_PCM )
{
//file->Write( &format.basic, sizeof( format.basic ) );
}
else if ( format . basic . formatTag = = FORMAT_ADPCM )
{
2012-11-26 18:58:24 +00:00
//file->Write( &format.basic, sizeof( format.basic ) );
file - > Write ( & format . extraSize , sizeof ( format . extraSize ) ) ;
file - > Write ( & format . extra . adpcm , sizeof ( format . extra . adpcm ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( format . basic . formatTag = = FORMAT_XMA2 )
{
2012-11-26 18:58:24 +00:00
//file->Write( &format.basic, sizeof( format.basic ) );
file - > Write ( & format . extraSize , sizeof ( format . extraSize ) ) ;
file - > Write ( & format . extra . xma2 , sizeof ( format . extra . xma2 ) ) ;
2012-11-28 15:47:07 +00:00
}
else if ( format . basic . formatTag = = FORMAT_EXTENSIBLE )
{
2012-11-26 18:58:24 +00:00
//file->Write( &format.basic, sizeof( format.basic ) );
file - > Write ( & format . extraSize , sizeof ( format . extraSize ) ) ;
file - > Write ( & format . extra . extensible , sizeof ( format . extra . extensible ) ) ;
2012-11-28 15:47:07 +00:00
}
else
{
2012-11-26 18:58:24 +00:00
return false ;
}
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : WriteWaveFormatDirect
2012-11-28 15:47:07 +00:00
Writes a wave format header to a file ptr ,
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWaveFile : : WriteSampleDataDirect ( idList < sampleData_t > & sampleData , idFile * file )
{
2012-11-26 18:58:24 +00:00
static const uint32 sample = ' smpl ' ;
file - > WriteBig ( sample ) ;
uint32 samplerData = sampleData . Num ( ) * 24 ;
uint32 chunkSize = 36 + samplerData ;
uint32 zero = 0 ;
uint32 numSamples = sampleData . Num ( ) ;
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
file - > Write ( & chunkSize , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & numSamples , sizeof ( uint32 ) ) ;
file - > Write ( & samplerData , sizeof ( uint32 ) ) ;
2012-11-28 15:47:07 +00:00
for ( int i = 0 ; i < sampleData . Num ( ) ; + + i )
{
2012-11-26 18:58:24 +00:00
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & sampleData [ i ] . start , sizeof ( uint32 ) ) ;
file - > Write ( & sampleData [ i ] . end , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
file - > Write ( & zero , sizeof ( uint32 ) ) ;
}
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : WriteWaveFormatDirect
Writes a data chunk to a file ptr
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWaveFile : : WriteDataDirect ( char * _data , uint32 size , idFile * file )
{
2012-11-26 18:58:24 +00:00
static const uint32 data = ' data ' ;
file - > WriteBig ( data ) ;
file - > Write ( & size , sizeof ( uint32 ) ) ;
file - > WriteBigArray ( _data , size ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : WriteWaveFormatDirect
2012-11-28 15:47:07 +00:00
Writes a wave header to a file ptr ,
2012-11-26 18:58:24 +00:00
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWaveFile : : WriteHeaderDirect ( uint32 fileSize , idFile * file )
{
2012-11-26 18:58:24 +00:00
static const uint32 riff = ' RIFF ' ;
static const uint32 wave = ' WAVE ' ;
file - > WriteBig ( riff ) ;
file - > WriteBig ( fileSize ) ;
file - > WriteBig ( wave ) ;
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : ReadLoopPoint
Reads a loop point from a ' smpl ' chunk in a wave file , returns 0 if none are found .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
bool idWaveFile : : ReadLoopData ( int & start , int & end )
{
2012-11-26 18:58:24 +00:00
uint32 chunkSize = SeekToChunk ( samplerChunk_t : : id ) ;
2012-11-28 15:47:07 +00:00
if ( chunkSize < sizeof ( samplerChunk_t ) )
{
2012-11-26 18:58:24 +00:00
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
samplerChunk_t smpl ;
Read ( & smpl , sizeof ( smpl ) ) ;
idSwap : : Little ( smpl . numSampleLoops ) ;
2012-11-28 15:47:07 +00:00
if ( smpl . numSampleLoops < 1 )
{
2012-11-26 18:58:24 +00:00
return false ; // this is possible returning false lets us know there are more then 1 sample look in the file and is not appropriate for traditional looping
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
sampleData_t smplData ;
Read ( & smplData , sizeof ( smplData ) ) ;
idSwap : : Little ( smplData . start ) ;
idSwap : : Little ( smplData . end ) ;
2012-11-28 15:47:07 +00:00
if ( smplData . type ! = 0 )
{
2012-11-26 18:58:24 +00:00
idLib : : Warning ( " Invalid loop type in %s " , file - > GetName ( ) ) ;
return false ;
}
2012-11-28 15:47:07 +00:00
2012-11-26 18:58:24 +00:00
start = smplData . start ;
end = smplData . end ;
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idWaveFile : : Close
Closes the file and frees resources .
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2012-11-28 15:47:07 +00:00
void idWaveFile : : Close ( )
{
if ( file ! = NULL )
{
2012-11-26 18:58:24 +00:00
delete file ;
file = NULL ;
}
chunks . SetNum ( 0 ) ;
}