예제 #1
0
int CWAVInputSource::AnalyzeSource()
{
	unsigned char *p = FULL_HEADER, *priff = NULL;

	// seek to the beginning (just in case)
	m_spIO->Seek(0, FILE_BEGIN);

	// get the file size
	m_nFileBytes = m_spIO->GetSize();

	// get the RIFF header
	RETURN_ON_ERROR(ReadSafe(m_spIO, p, sizeof(RIFF_HEADER)))

	// make sure the RIFF header is valid
	if (!(p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F'))
		return ERROR_INVALID_INPUT_FILE;
	p += sizeof(RIFF_HEADER);

	// read the data type header
	RETURN_ON_ERROR(ReadSafe(m_spIO, p, sizeof(DATA_TYPE_ID_HEADER)))

	// make sure it's the right data type
	if (!(p[0] == 'W' && p[1] == 'A' && p[2] == 'V' && p[3] == 'E'))
		return ERROR_INVALID_INPUT_FILE;
	p += sizeof(DATA_TYPE_ID_HEADER);

	// find the 'fmt ' chunk
	RETURN_ON_ERROR(ReadSafe(m_spIO, p, sizeof(RIFF_CHUNK_HEADER)))

	while (!(p[0] == 'f' && p[1] == 'm' && p[2] == 't' && p[3] == ' '))
	{
		p += sizeof(RIFF_CHUNK_HEADER);

		// move the file pointer to the end of this chunk
		RETURN_ON_ERROR(ReadSafe(m_spIO, p, LE_LONG(p+4)))
		p += LE_LONG(p+4);

		// check again for the data chunk
		RETURN_ON_ERROR(ReadSafe(m_spIO, p, sizeof(RIFF_CHUNK_HEADER)))
    }

	priff = p+4;
	p += sizeof(RIFF_CHUNK_HEADER);

	// read the format info
	RETURN_ON_ERROR(ReadSafe(m_spIO, p, sizeof(WAV_FORMAT_HEADER)))

	// error check the header to see if we support it
	if (LE_SHORT(p) != 1)
		return ERROR_INVALID_INPUT_FILE;

	// copy the format information to the WAVEFORMATEX passed in
	FillWaveFormatEx(&m_wfeSource, LE_LONG(p+4), LE_SHORT(p+14), LE_SHORT(p+2));

	p += sizeof(WAV_FORMAT_HEADER);

	// skip over any extra data in the header
	int nWAVFormatHeaderExtra = LE_LONG(priff) - sizeof(WAV_FORMAT_HEADER);
	if (nWAVFormatHeaderExtra < 0)
		return ERROR_INVALID_INPUT_FILE;
	else {
		RETURN_ON_ERROR(ReadSafe(m_spIO, p, nWAVFormatHeaderExtra))
		p += nWAVFormatHeaderExtra;
	}

	// find the data chunk
	RETURN_ON_ERROR(ReadSafe(m_spIO, p, sizeof(RIFF_CHUNK_HEADER)))

	while (!(p[0] == 'd' && p[1] == 'a' && p[2] == 't' && p[3] == 'a'))
	{
		p += sizeof(RIFF_CHUNK_HEADER);

		// move the file pointer to the end of this chunk
		RETURN_ON_ERROR(ReadSafe(m_spIO, p, LE_LONG(p+4)))
		p += LE_LONG(p+4);

		// check again for the data chunk
		RETURN_ON_ERROR(ReadSafe(m_spIO, p, sizeof(RIFF_CHUNK_HEADER)))
	}

	// we're at the data block
	m_nDataBytes = LE_LONG(p+4);
	if (m_nDataBytes < 0)
		m_nDataBytes = m_nFileBytes - m_nHeaderBytes;

	p += sizeof(RIFF_CHUNK_HEADER);

	m_nHeaderBytes = p - FULL_HEADER;

	// make sure the data bytes is a whole number of blocks
	if ((m_nDataBytes % m_wfeSource.nBlockAlign) != 0)
		return ERROR_INVALID_INPUT_FILE;

	// calculate the terminating byts
	m_nTerminatingBytes = 0;

	// we made it this far, everything must be cool
	return ERROR_SUCCESS;
}
예제 #2
0
int CWAVInputSource::AnalyzeSource()
{
    // seek to the beginning (just in case)
    m_spIO->Seek(0, FILE_BEGIN);
    
    // get the file size
    m_nFileBytes = m_spIO->GetSize();

    // get the RIFF header
    RIFF_HEADER RIFFHeader;
    RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFHeader, sizeof(RIFFHeader))) 

    // make sure the RIFF header is valid
    if (!(RIFFHeader.cRIFF[0] == 'R' && RIFFHeader.cRIFF[1] == 'I' && RIFFHeader.cRIFF[2] == 'F' && RIFFHeader.cRIFF[3] == 'F')) 
        return ERROR_INVALID_INPUT_FILE;

    // read the data type header
    DATA_TYPE_ID_HEADER DataTypeIDHeader;
    RETURN_ON_ERROR(ReadSafe(m_spIO, &DataTypeIDHeader, sizeof(DataTypeIDHeader))) 
    
    // make sure it's the right data type
    if (!(DataTypeIDHeader.cDataTypeID[0] == 'W' && DataTypeIDHeader.cDataTypeID[1] == 'A' && DataTypeIDHeader.cDataTypeID[2] == 'V' && DataTypeIDHeader.cDataTypeID[3] == 'E')) 
        return ERROR_INVALID_INPUT_FILE;

    // find the 'fmt ' chunk
    RIFF_CHUNK_HEADER RIFFChunkHeader;
    RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFChunkHeader, sizeof(RIFFChunkHeader))) 
    
    while (!(RIFFChunkHeader.cChunkLabel[0] == 'f' && RIFFChunkHeader.cChunkLabel[1] == 'm' && RIFFChunkHeader.cChunkLabel[2] == 't' && RIFFChunkHeader.cChunkLabel[3] == ' ')) 
    {
        // move the file pointer to the end of this chunk
        m_spIO->Seek(RIFFChunkHeader.nChunkBytes, FILE_CURRENT);

        // check again for the data chunk
        RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFChunkHeader, sizeof(RIFFChunkHeader))) 
    }
    
    // read the format info
    WAV_FORMAT_HEADER WAVFormatHeader;
    RETURN_ON_ERROR(ReadSafe(m_spIO, &WAVFormatHeader, sizeof(WAVFormatHeader))) 

    // error check the header to see if we support it
    if (WAVFormatHeader.nFormatTag != 1)
        return ERROR_INVALID_INPUT_FILE;

    // copy the format information to the WAVEFORMATEX passed in
    FillWaveFormatEx(&m_wfeSource, WAVFormatHeader.nSamplesPerSecond, WAVFormatHeader.nBitsPerSample, WAVFormatHeader.nChannels);

    // skip over any extra data in the header
    int nWAVFormatHeaderExtra = RIFFChunkHeader.nChunkBytes - sizeof(WAVFormatHeader);
    if (nWAVFormatHeaderExtra < 0)
        return ERROR_INVALID_INPUT_FILE;
    else
        m_spIO->Seek(nWAVFormatHeaderExtra, FILE_CURRENT);
    
    // find the data chunk
    RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFChunkHeader, sizeof(RIFFChunkHeader))) 

    while (!(RIFFChunkHeader.cChunkLabel[0] == 'd' && RIFFChunkHeader.cChunkLabel[1] == 'a' && RIFFChunkHeader.cChunkLabel[2] == 't' && RIFFChunkHeader.cChunkLabel[3] == 'a')) 
    {
        // move the file pointer to the end of this chunk
        m_spIO->Seek(RIFFChunkHeader.nChunkBytes, FILE_CURRENT);

        // check again for the data chunk
        RETURN_ON_ERROR(ReadSafe(m_spIO, &RIFFChunkHeader, sizeof(RIFFChunkHeader))) 
    }

    // we're at the data block
    m_nHeaderBytes = m_spIO->GetPosition();
    m_nDataBytes = RIFFChunkHeader.nChunkBytes;
    if (m_nDataBytes < 0)
        m_nDataBytes = m_nFileBytes - m_nHeaderBytes;

    // make sure the data bytes is a whole number of blocks
    if ((m_nDataBytes % m_wfeSource.nBlockAlign) != 0)
        return ERROR_INVALID_INPUT_FILE;

    // calculate the terminating byts
    m_nTerminatingBytes = m_nFileBytes - m_nDataBytes - m_nHeaderBytes;
    
    // we made it this far, everything must be cool
    return ERROR_SUCCESS;
}