Exemple #1
0
//--------------------------------------------------------------------------------------
// Name: ReadSample()
// Desc: Reads data from the audio file.
//--------------------------------------------------------------------------------------
HRESULT WaveFile::ReadSample( DWORD dwPosition, VOID* pBuffer,
                              DWORD dwBufferSize, DWORD* pdwRead ) const
{
    HRESULT hr = S_OK;
    hr = ReadSampleRaw(dwPosition, pBuffer, dwBufferSize, pdwRead);

    if (FAILED( hr ))
    {
        return hr;
    }

    // Check bit size for endianness conversion.
    WAVEFORMATEXTENSIBLE wfxFormat;
    GetFormat( &wfxFormat );

    //Endianness conversion
    switch( wfxFormat.Format.wFormatTag )
    {
        case WAVE_FORMAT_PCM:
            if( wfxFormat.Format.wBitsPerSample == 16 )
            {
                SHORT* pBufferShort = ( SHORT* )pBuffer;
                for( DWORD i = 0; i < dwBufferSize / sizeof( SHORT ); i++ )
                    pBufferShort[i] = __loadshortbytereverse( 0, &pBufferShort[i] );
            }
            break;

        case WAVE_FORMAT_EXTENSIBLE:
            if( wfxFormat.Format.wBitsPerSample == 16 )
            {
                SHORT* pBufferShort = ( SHORT* )pBuffer;
                for( DWORD i = 0; i < dwBufferSize / sizeof( SHORT ); i++ )
                    pBufferShort[i] = __loadshortbytereverse( 0, &pBufferShort[i] );
            }
            else if( wfxFormat.Format.wBitsPerSample == 32 )
            {
                DWORD* pBufferDWord = ( DWORD* )pBuffer;
                for( DWORD i = 0; i < dwBufferSize / sizeof( DWORD ); i++ )
                    pBufferDWord[i] = __loadwordbytereverse( 0, &pBufferDWord[i] );
            }
            // 24 doesn't need converted...
            break;
    }

    return hr;
}
Exemple #2
0
//--------------------------------------------------------------------------------------
// Name: Open()
// Desc: Opens an existing chunk
//--------------------------------------------------------------------------------------
HRESULT RiffChunk::Open()
{
    LONG lOffset = 0;

    // Seek to the first byte of the parent chunk's data section
    if( m_pParentChunk )
    {
        lOffset = m_pParentChunk->m_dwDataOffset;

        // Special case the RIFF chunk
        if( ATG_FOURCC_RIFF == m_pParentChunk->m_fccChunkId )
            lOffset += sizeof( FOURCC );
    }

    // Read each child chunk header until we find the one we're looking for
    for(; ; )
    {
        if( INVALID_SET_FILE_POINTER == SetFilePointer( m_hFile, lOffset, NULL, FILE_BEGIN ) )
            return HRESULT_FROM_WIN32( GetLastError() );

        RIFFHEADER rhRiffHeader;
        DWORD dwRead;
        if( 0 == ReadFile( m_hFile, &rhRiffHeader, sizeof( rhRiffHeader ), &dwRead, NULL ) )
            return HRESULT_FROM_WIN32( GetLastError() );
        rhRiffHeader.dwDataSize = __loadwordbytereverse( 0, &rhRiffHeader.dwDataSize );

        // Hit EOF without finding it
        if( 0 == dwRead )
            return E_FAIL;

        // Check if we found the one we're looking for
        if( m_fccChunkId == rhRiffHeader.fccChunkId )
        {
            // Save the chunk size and data offset
            m_dwDataOffset = lOffset + sizeof( rhRiffHeader );
            m_dwDataSize = rhRiffHeader.dwDataSize;

            // Success
            m_dwFlags |= RIFFCHUNK_FLAGS_VALID;

            return S_OK;
        }

        lOffset += sizeof( rhRiffHeader ) + rhRiffHeader.dwDataSize;
    }
}
Exemple #3
0
int LoadZIMPtr(uint8_t *zim, int datasize, int *width, int *height, int *flags, uint8 **image) {
	if (zim[0] != 'Z' || zim[1] != 'I' || zim[2] != 'M' || zim[3] != 'G') {
		ELOG("Not a ZIM file");
		return 0;
	}
#ifndef _XBOX
	memcpy(width, zim + 4, 4);
	memcpy(height, zim + 8, 4);
	memcpy(flags, zim + 12, 4);
#else
	*width = __loadwordbytereverse(4, zim);
	*height = __loadwordbytereverse(8, zim);
	*flags = __loadwordbytereverse(12, zim);
#endif

	int num_levels = 1;
	int image_data_size[ZIM_MAX_MIP_LEVELS];
	if (*flags & ZIM_HAS_MIPS) {
		num_levels = log2i(*width < *height ? *width : *height) + 1;
	}
	int total_data_size = 0;
	for (int i = 0; i < num_levels; i++) {
		if (i > 0) {
			width[i] = width[i-1] / 2;
			height[i] = height[i-1] / 2;
		}
		switch (*flags & ZIM_FORMAT_MASK) {
		case ZIM_RGBA8888:
			image_data_size[i] = width[i] * height[i] * 4; 
			break;
		case ZIM_RGBA4444:
		case ZIM_RGB565:
			image_data_size[i] = width[i] * height[i] * 2;
			break;
		case ZIM_ETC1:
			{
				int data_width = width[i];
				int data_height = height[i];
				if (data_width < 4) data_width = 4;
				if (data_height < 4) data_height = 4;
				image_data_size[i] = data_width * data_height / 2;
				break;
			}
		default:
			ELOG("Invalid ZIM format %i", *flags & ZIM_FORMAT_MASK);
			return 0;
		}
		total_data_size += image_data_size[i];
	}

	if (total_data_size == 0)
	{
		ELOG("Invalid ZIM data size 0");
		return 0;
	}

	image[0] = (uint8 *)malloc(total_data_size);
	for (int i = 1; i < num_levels; i++) {
		image[i] = image[i-1] + image_data_size[i-1];
	}

	if (*flags & ZIM_ZLIB_COMPRESSED) {
		long outlen = total_data_size;
		if (Z_OK != ezuncompress(*image, &outlen, (unsigned char *)(zim + 16), datasize - 16)) {
			free(*image);
			*image = 0;
			return 0;
		}
		if (outlen != total_data_size) {
			ELOG("Wrong size data in ZIM: %i vs %i", (int)outlen, (int)total_data_size);
		}
	} else {
		memcpy(*image, zim + 16, datasize - 16);
		if (datasize - 16 != total_data_size) {
			ELOG("Wrong size data in ZIM: %i vs %i", (int)(datasize-16), (int)total_data_size);
		}
	}
	return num_levels;
}
Exemple #4
0
//--------------------------------------------------------------------------------------
// Name: GetLoopRegion()
// Desc: Gets the loop region, in terms of samples
//--------------------------------------------------------------------------------------
HRESULT WaveFile::GetLoopRegion( DWORD* pdwStart, DWORD* pdwLength ) const
{
    assert( pdwStart != NULL );
    assert( pdwLength != NULL );
    HRESULT hr = S_OK;

    *pdwStart = 0;
    *pdwLength = 0;

    // First, look for a MIDI-style SMPL chunk, then for a DLS-style WSMP chunk.
    BOOL bGotLoopRegion = FALSE;
    if( !bGotLoopRegion && m_SamplerChunk.IsValid() )
    {
        // Read the SAMPLER struct from the chunk
        SAMPLER smpl;
        hr = m_SamplerChunk.ReadData( 0, &smpl, sizeof( SAMPLER ), NULL );
        if( FAILED( hr ) )
            return hr;

        //Endianness conversion
        LONG* pLong = ( LONG* )&smpl;
        for( INT i = 0; i < sizeof( SAMPLER ) / sizeof( LONG ); i++ )
            *pLong++ = __loadwordbytereverse( i, &smpl );


        // Check if the chunk contains any loop regions
        if( smpl.dwNumSampleLoops > 0 )
        {
            SAMPLER_LOOP smpl_loop;
            hr = m_SamplerChunk.ReadData( sizeof( SAMPLER ), &smpl_loop, sizeof( SAMPLER_LOOP ), NULL );
            if( FAILED( hr ) )
                return E_FAIL;

            //Endianness conversion
            pLong = ( LONG* )&smpl_loop;
            for( INT i = 0; i < sizeof( SAMPLER_LOOP ) / sizeof( LONG ); i++ )
                *pLong++ = __loadwordbytereverse( i, &smpl_loop );

            // Documentation on the SMPL chunk indicates that dwStart and
            // dwEnd are stored as byte-offsets, rather than sample counts,
            // but SoundForge stores sample counts, so we'll go with that.
            *pdwStart = smpl_loop.dwStart;
            *pdwLength = smpl_loop.dwEnd - smpl_loop.dwStart + 1;
            bGotLoopRegion = TRUE;
        }
    }

    if( !bGotLoopRegion && m_WaveSampleChunk.IsValid() )
    {
        // Read the WAVESAMPLE struct from the chunk
        WAVESAMPLE ws;
        hr = m_WaveSampleChunk.ReadData( 0, &ws, sizeof( WAVESAMPLE ), NULL );
        if( FAILED( hr ) )
            return hr;

        // Endianness conversion
        ws.dwSize = __loadwordbytereverse( 0, &ws.dwSize );
        ws.UnityNote = __loadshortbytereverse( 0, &ws.UnityNote );
        ws.FineTune = __loadshortbytereverse( 0, &ws.FineTune );
        ws.Gain = __loadwordbytereverse( 0, &ws.Gain );
        ws.dwOptions = __loadwordbytereverse( 0, &ws.dwOptions );
        ws.dwSampleLoops = __loadwordbytereverse( 0, &ws.dwSampleLoops );

        // Check if the chunk contains any loop regions
        if( ws.dwSampleLoops > 0 )
        {
            // Read the loop region
            WAVESAMPLE_LOOP wsl;
            hr = m_WaveSampleChunk.ReadData( ws.dwSize, &wsl, sizeof( WAVESAMPLE_LOOP ), NULL );
            if( FAILED( hr ) )
                return hr;

            //Endianness conversion
            LONG* l = ( LONG* )&wsl;
            for( INT i = 0; i < sizeof( WAVESAMPLE_LOOP ) / sizeof( LONG ); i++ )
                *l++ = __loadwordbytereverse( i, &wsl );

            // Fill output vars with the loop region
            *pdwStart = wsl.dwLoopStart;
            *pdwLength = wsl.dwLoopLength;
            bGotLoopRegion = TRUE;
        }
    }

    // Couldn't find either chunk, or they didn't contain loop points
    if( !bGotLoopRegion )
        return E_FAIL;

    return S_OK;
}
Exemple #5
0
//--------------------------------------------------------------------------------------
// Name: GetFormat()
// Desc: Gets the wave file format.
//--------------------------------------------------------------------------------------
HRESULT WaveFile::GetFormat( WAVEFORMATEXTENSIBLE* pwfxFormat, XMA2WAVEFORMATEX* pXma2Format ) const
{
    assert( pwfxFormat );

    DWORD dwValidSize = m_FormatChunk.GetDataSize();

    // Must be at least as large as a WAVEFORMAT to be valid
    if( dwValidSize < sizeof( WAVEFORMAT ) )
        return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );

    // Read the format chunk into the buffer
    HRESULT hr = m_FormatChunk.ReadData( 0, pwfxFormat, min( dwValidSize, sizeof( WAVEFORMATEXTENSIBLE ) ), NULL );
    if( FAILED( hr ) )
        return hr;

    // Endian conversion for WAVEFORMAT base structure
    pwfxFormat->Format.wFormatTag = __loadshortbytereverse( 0, &pwfxFormat->Format.wFormatTag );
    pwfxFormat->Format.nChannels = __loadshortbytereverse( 0, &pwfxFormat->Format.nChannels );
    pwfxFormat->Format.nSamplesPerSec = __loadwordbytereverse( 0, &pwfxFormat->Format.nSamplesPerSec );
    pwfxFormat->Format.nAvgBytesPerSec = __loadwordbytereverse( 0, &pwfxFormat->Format.nAvgBytesPerSec );
    pwfxFormat->Format.nBlockAlign = __loadshortbytereverse( 0, &pwfxFormat->Format.nBlockAlign );

    switch( pwfxFormat->Format.wFormatTag )
    {
        case WAVE_FORMAT_PCM:
        case WAVE_FORMAT_WMAUDIO3:
        case WAVE_FORMAT_WMAUDIO2:
            if( dwValidSize < sizeof( PCMWAVEFORMAT ) )
                return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );

            pwfxFormat->Format.wBitsPerSample = __loadshortbytereverse( 0, &pwfxFormat->Format.wBitsPerSample );
            break;

        case WAVE_FORMAT_EXTENSIBLE:
            if( dwValidSize < sizeof( WAVEFORMATEXTENSIBLE ) )
                return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );

            // Endianness conversion
            pwfxFormat->Format.wBitsPerSample = __loadshortbytereverse( 0, &pwfxFormat->Format.wBitsPerSample );
            pwfxFormat->Format.cbSize = __loadshortbytereverse( 0, &pwfxFormat->Format.cbSize );

            pwfxFormat->Samples.wReserved = __loadshortbytereverse( 0, &pwfxFormat->Samples.wReserved );
            pwfxFormat->dwChannelMask = __loadwordbytereverse( 0, &pwfxFormat->dwChannelMask );
            pwfxFormat->SubFormat.Data1 = __loadwordbytereverse( 0, &pwfxFormat->SubFormat.Data1 );
            pwfxFormat->SubFormat.Data2 = __loadshortbytereverse( 0, &pwfxFormat->SubFormat.Data2 );
            pwfxFormat->SubFormat.Data3 = __loadshortbytereverse( 0, &pwfxFormat->SubFormat.Data3 );
            // Data4 is a array of char, not needed to convert
            break;

        case WAVE_FORMAT_XMA2:
            if( dwValidSize != sizeof( XMA2WAVEFORMATEX ) )
                return HRESULT_FROM_WIN32( ERROR_INVALID_DATA );

            // Need second structure to store the result
            if( !pXma2Format )
                return HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER );

            hr = m_FormatChunk.ReadData( 0, pXma2Format, sizeof( XMA2WAVEFORMATEX ), NULL );
            if( FAILED( hr ) )
                return hr;

            // Endian conversion
            {
                pwfxFormat->Format.wBitsPerSample = __loadshortbytereverse( 0, &pwfxFormat->Format.wBitsPerSample );
                pwfxFormat->Format.cbSize = __loadshortbytereverse( 0, &pwfxFormat->Format.cbSize );

                pXma2Format->wfx = pwfxFormat->Format;

                pXma2Format->NumStreams = __loadshortbytereverse( 0, &pXma2Format->NumStreams );
                pXma2Format->ChannelMask = __loadwordbytereverse( 0, &pXma2Format->ChannelMask );
                pXma2Format->SamplesEncoded = __loadwordbytereverse( 0, &pXma2Format->SamplesEncoded );
                pXma2Format->BytesPerBlock = __loadwordbytereverse( 0, &pXma2Format->BytesPerBlock );
                pXma2Format->PlayBegin = __loadwordbytereverse( 0, &pXma2Format->PlayBegin );
                pXma2Format->PlayLength = __loadwordbytereverse( 0, &pXma2Format->PlayLength );
                pXma2Format->LoopBegin = __loadwordbytereverse( 0, &pXma2Format->LoopBegin );
                pXma2Format->LoopLength = __loadwordbytereverse( 0, &pXma2Format->LoopLength );
                pXma2Format->BlockCount = __loadshortbytereverse( 0, &pXma2Format->BlockCount );
            }
            break;

        default:
            // Unsupported!
            return HRESULT_FROM_WIN32( ERROR_NOT_SUPPORTED );
    }

    // Zero out remaining bytes, in case enough bytes were not read
    if( dwValidSize < sizeof( WAVEFORMATEXTENSIBLE ) )
        ZeroMemory( ( BYTE* )pwfxFormat + dwValidSize, sizeof( WAVEFORMATEXTENSIBLE ) - dwValidSize );

    return S_OK;
}