//----------------------------------------------------------------------------- // Purpose: reads the actual sample data and parses it // Input : &walk - RIFF file //----------------------------------------------------------------------------- void CAudioSourceMemWave::ParseDataChunk( IterateRIFF &walk ) { int size = walk.ChunkSize(); // create a buffer for the samples m_pData = new char[size]; // load them into memory walk.ChunkRead( m_pData ); if ( m_format == WAVE_FORMAT_PCM ) { // number of samples loaded m_sampleCount = size / m_sampleSize; // some samples need to be converted ConvertSamples( m_pData, m_sampleCount ); } else if ( m_format == WAVE_FORMAT_ADPCM ) { // The ADPCM mixers treat the wave source as a flat file of bytes. m_sampleSize = 1; // Since each "sample" is a byte (this is a flat file), the number of samples is the file size m_sampleCount = size; // file says 4, output is 16 m_bits = 16; } }
//----------------------------------------------------------------------------- // Purpose: // Input : &walk - //----------------------------------------------------------------------------- void CSoundCombiner::ParseSentence( CSentence& sentence, IterateRIFF &walk ) { CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); buf.EnsureCapacity( walk.ChunkSize() ); walk.ChunkRead( buf.Base() ); buf.SeekPut( CUtlBuffer::SEEK_HEAD, walk.ChunkSize() ); sentence.InitFromDataChunk( buf.Base(), buf.TellPut() ); }
//----------------------------------------------------------------------------- // Purpose: Bastardized construction routine. This is just to avoid complex // constructor functions so code can be shared more easily by sub-classes // Input : *pFormatBuffer - RIFF header // formatSize - header size // &walk - RIFF file //----------------------------------------------------------------------------- void CAudioSourceWave::Setup( const char *pFormatBuffer, int formatSize, IterateRIFF &walk ) { Init( pFormatBuffer, formatSize ); while ( walk.ChunkAvailable() ) { ParseChunk( walk, walk.ChunkName() ); walk.ChunkNext(); } }
//----------------------------------------------------------------------------- // Purpose: // Input : &walk - //----------------------------------------------------------------------------- void CAudioSourceWave::ParseSentence( IterateRIFF &walk ) { CUtlBuffer buf( 0, 0, true ); buf.EnsureCapacity( walk.ChunkSize() ); walk.ChunkRead( buf.Base() ); buf.SeekPut( CUtlBuffer::SEEK_HEAD, walk.ChunkSize() ); m_Sentence.InitFromDataChunk( buf.Base(), buf.TellPut() ); }
//----------------------------------------------------------------------------- // Purpose: parses loop information from a cue chunk // Input : &walk - RIFF iterator // Output : int loop start position //----------------------------------------------------------------------------- int CAudioSourceWave::ParseCueChunk( IterateRIFF &walk ) { // Cue chunk as specified by RIFF format // see $/research/jay/sound/riffnew.htm struct { unsigned int dwName; unsigned int dwPosition; unsigned int fccChunk; unsigned int dwChunkStart; unsigned int dwBlockStart; unsigned int dwSampleOffset; } cue_chunk; int cueCount; // assume that the cue chunk stored in the wave is the start of the loop // assume only one cue chunk, UNDONE: Test this assumption here? cueCount = walk.ChunkReadInt(); walk.ChunkReadPartial( &cue_chunk, sizeof(cue_chunk) ); return cue_chunk.dwSampleOffset; }
//----------------------------------------------------------------------------- // Purpose: Parse base chunks // Input : &walk - riff file to parse // : chunkName - name of the chunk to parse //----------------------------------------------------------------------------- // UNDONE: Move parsing loop here and drop each chunk into a virtual function // instead of this being virtual. void CAudioSourceWave::ParseChunk( IterateRIFF &walk, int chunkName ) { switch( chunkName ) { case WAVE_CUE: { m_loopStart = ParseCueChunk( walk ); } break; case WAVE_VALVEDATA: { ParseSentence( walk ); } break; // unknown/don't care default: { ChunkError( walk.ChunkName() ); } break; } }
//----------------------------------------------------------------------------- // Purpose: Set up a sub-chunk iterator // Input : &parent - parent iterator //----------------------------------------------------------------------------- IterateRIFF::IterateRIFF( IterateRIFF &parent ) : m_riff(parent.m_riff), m_size(parent.ChunkSize()) { m_start = parent.ChunkFilePosition(); ChunkSetup(); }