📄 cwavfile.cpp
字号:
// cWavFile.cpp: implementation of the cWavFile class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "cWavFile.h"
#include "cApplication.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
// Name: CWaveFile::CWaveFile()
// Desc: Constructs the class. Call Open() to open a wave file for reading.
// Then call Read() as needed. Calling the destructor or Close()
// will close the file.
//-----------------------------------------------------------------------------
cWavFile::cWavFile()
{
m_pwfx = NULL;
m_hmmio = NULL;
m_pResourceBuffer = NULL;
m_dwSize = 0;
m_bIsReadingFromMemory = FALSE;
}
//-----------------------------------------------------------------------------
// Name: CWaveFile::~CWaveFile()
// Desc: Destructs the class
//-----------------------------------------------------------------------------
cWavFile::~cWavFile()
{
Close();
if( !m_bIsReadingFromMemory )
if( m_pwfx )
{
delete[] m_pwfx;
m_pwfx = NULL;
}
}
//-----------------------------------------------------------------------------
// Name: CWaveFile::Open()
// Desc: Opens a wave file for reading
//-----------------------------------------------------------------------------
HRESULT cWavFile::Open( LPTSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags )
{
HRESULT hr;
m_dwFlags = dwFlags;
m_bIsReadingFromMemory = FALSE;
if( m_dwFlags == WAVEFILE_READ )
{
if( strFileName == NULL )
return E_INVALIDARG;
if( m_pwfx )
{
delete[] m_pwfx;
m_pwfx = NULL;
}
HRSRC hResInfo;
HGLOBAL hResData;
DWORD dwSize;
VOID* pvRes;
// Loading it as a file failed, so try it as a resource
if( NULL == ( hResInfo = FindResource( GetMainApp()->GetInstHandle(), strFileName, TEXT("WAVE") ) ) )
{
if( NULL == ( hResInfo = FindResource( GetMainApp()->GetInstHandle(), strFileName, TEXT("WAV") ) ) )
m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ );
}
if(hResInfo != NULL)
{
if( NULL == ( hResData = LoadResource( NULL, hResInfo ) ) )
return DXTRACE_ERR( TEXT("LoadResource"), E_FAIL );
if( 0 == ( dwSize = SizeofResource( NULL, hResInfo ) ) )
return DXTRACE_ERR( TEXT("SizeofResource"), E_FAIL );
if( NULL == ( pvRes = LockResource( hResData ) ) )
return DXTRACE_ERR( TEXT("LockResource"), E_FAIL );
m_pResourceBuffer = new CHAR[ dwSize ];
memcpy( m_pResourceBuffer, pvRes, dwSize );
MMIOINFO mmioInfo;
ZeroMemory( &mmioInfo, sizeof(mmioInfo) );
mmioInfo.fccIOProc = FOURCC_MEM;
mmioInfo.cchBuffer = dwSize;
mmioInfo.pchBuffer = (CHAR*) m_pResourceBuffer;
m_hmmio = mmioOpen( NULL, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ );
}
if( NULL == m_hmmio )
{
}
if( FAILED( hr = ReadMMIO() ) )
{
// ReadMMIO will fail if its an not a wave file
mmioClose( m_hmmio, 0 );
return DXTRACE_ERR_NOMSGBOX( TEXT("ReadMMIO"), hr );
}
if( FAILED( hr = ResetFile() ) )
return DXTRACE_ERR( TEXT("ResetFile"), hr );
// After the reset, the size of the wav file is m_ck.cksize so store it now
m_dwSize = m_ck.cksize;
}
else
{
m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF |
MMIO_READWRITE |
MMIO_CREATE );
if( NULL == m_hmmio )
return DXTRACE_ERR( TEXT("mmioOpen"), E_FAIL );
if( FAILED( hr = WriteMMIO( pwfx ) ) )
{
mmioClose( m_hmmio, 0 );
return DXTRACE_ERR( TEXT("WriteMMIO"), hr );
}
if( FAILED( hr = ResetFile() ) )
return DXTRACE_ERR( TEXT("ResetFile"), hr );
}
return hr;
}
//-----------------------------------------------------------------------------
// Name: CWaveFile::OpenFromMemory()
// Desc: copy data to CWaveFile member variable from memory
//-----------------------------------------------------------------------------
HRESULT cWavFile::OpenFromMemory( BYTE* pbData, ULONG ulDataSize,
WAVEFORMATEX* pwfx, DWORD dwFlags )
{
m_pwfx = pwfx;
m_ulDataSize = ulDataSize;
m_pbData = pbData;
m_pbDataCur = m_pbData;
m_bIsReadingFromMemory = TRUE;
if( dwFlags != WAVEFILE_READ )
return E_NOTIMPL;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CWaveFile::ReadMMIO()
// Desc: Support function for reading from a multimedia I/O stream.
// m_hmmio must be valid before calling. This function uses it to
// update m_ckRiff, and m_pwfx.
//-----------------------------------------------------------------------------
HRESULT cWavFile::ReadMMIO()
{
MMCKINFO ckIn; // chunk info. for general use.
PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in.
m_pwfx = NULL;
if( ( 0 != mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) )
return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL );
// Check to make sure this is a valid wave file
if( (m_ckRiff.ckid != FOURCC_RIFF) ||
(m_ckRiff.fccType != mmioFOURCC('W', 'A', 'V', 'E') ) )
return DXTRACE_ERR_NOMSGBOX( TEXT("mmioFOURCC"), E_FAIL );
// Search the input file for for the 'fmt ' chunk.
ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
if( 0 != mmioDescend( m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK ) )
return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL );
// Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
// if there are extra parameters at the end, we'll ignore them
if( ckIn.cksize < (LONG) sizeof(PCMWAVEFORMAT) )
return DXTRACE_ERR( TEXT("sizeof(PCMWAVEFORMAT)"), E_FAIL );
// Read the 'fmt ' chunk into <pcmWaveFormat>.
if( mmioRead( m_hmmio, (HPSTR) &pcmWaveFormat,
sizeof(pcmWaveFormat)) != sizeof(pcmWaveFormat) )
return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL );
// Allocate the waveformatex, but if its not pcm format, read the next
// word, and thats how many extra bytes to allocate.
if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM )
{
m_pwfx = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) ];
if( NULL == m_pwfx )
return DXTRACE_ERR( TEXT("m_pwfx"), E_FAIL );
// Copy the bytes from the pcm structure to the waveformatex structure
memcpy( m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat) );
m_pwfx->cbSize = 0;
}
else
{
// Read in length of extra bytes.
WORD cbExtraBytes = 0L;
if( mmioRead( m_hmmio, (CHAR*)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD) )
return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL );
m_pwfx = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) + cbExtraBytes ];
if( NULL == m_pwfx )
return DXTRACE_ERR( TEXT("new"), E_FAIL );
// Copy the bytes from the pcm structure to the waveformatex structure
memcpy( m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat) );
m_pwfx->cbSize = cbExtraBytes;
// Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
if( mmioRead( m_hmmio, (CHAR*)(((BYTE*)&(m_pwfx->cbSize))+sizeof(WORD)),
cbExtraBytes ) != cbExtraBytes )
{
if( m_pwfx )
{
delete m_pwfx;
m_pwfx = NULL;
}
return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL );
}
}
// Ascend the input file out of the 'fmt ' chunk.
if( 0 != mmioAscend( m_hmmio, &ckIn, 0 ) )
{
if( m_pwfx )
{
delete m_pwfx;
m_pwfx = NULL;
}
return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: CWaveFile::GetSize()
// Desc: Retuns the size of the read access wave file
//-----------------------------------------------------------------------------
DWORD cWavFile::GetSize()
{
return m_dwSize;
}
//-----------------------------------------------------------------------------
// Name: CWaveFile::ResetFile()
// Desc: Resets the internal m_ck pointer so reading starts from the
// beginning of the file again
//-----------------------------------------------------------------------------
HRESULT cWavFile::ResetFile()
{
if( m_bIsReadingFromMemory )
{
m_pbDataCur = m_pbData;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -