続きです。今回はWaveファイルを読み込んで解析する処理です。
mmioというマルチメディア入出力関数があるので、それを使って解析すればOKです。
前回のCAudioBaseクラスと今回のCAudioWaveクラスの上にCAudioクラスという緩衝材を入れてますが、ほとんどCAudioBaseと同じなので省略します。
これでようやく音が鳴るようになりました。次はまた当たり判定かなぁ。いい加減当たり判定もFIXしたいところ。
//-----------------------------------------------------------------------------
// 生成
CAudioWave::CAudioWave()
{
m_pwfx=NULL;
m_hmmio=NULL;
m_pResourceBuffer=NULL;
m_dwSize=0;
}
//-----------------------------------------------------------------------------
// 解放
CAudioWave::~CAudioWave()
{
Close();
SAFE_DELETE_ARRAY(m_pwfx);
}
//-----------------------------------------------------------------------------
// オープン
HRESULT CAudioWave::Open(LPSTR strFileName, WAVEFORMATEX* pwfx)
{
HRESULT hr;
if (strFileName==NULL) {
return FALSE;
}
SAFE_DELETE_ARRAY(m_pwfx);
// ファイルオープン
m_hmmio=mmioOpen(strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ);
if (FAILED(hr=ReadMMIO())) {
mmioClose(m_hmmio, 0);
return FALSE;
}
if (FAILED(ResetFile())) {
return FALSE;
}
// ファイルサイズ保持
m_dwSize=m_ck.cksize;
return TRUE;
}
//-----------------------------------------------------------------------------
// マルチメディア関数で読み込み
HRESULT CAudioWave::ReadMMIO()
{
MMCKINFO ckIn;
PCMWAVEFORMAT pcmWaveFormat;
m_pwfx=NULL;
if ((0!=mmioDescend(m_hmmio, &m_ckRiff, NULL, 0))) {
return E_FAIL;
}
// Waveファイルかどうか
if ((m_ckRiff.ckid!=FOURCC_RIFF) || (m_ckRiff.fccType!=mmioFOURCC('W', 'A', 'V', 'E'))) {
return E_FAIL;
}
// FMTチャンク検索
ckIn.ckid=mmioFOURCC('f', 'm', 't', ' ');
if (0!=mmioDescend(m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK)) {
return E_FAIL;
}
// pcmWaveFormat取得
if (mmioRead(m_hmmio, (HPSTR)&pcmWaveFormat, sizeof(pcmWaveFormat))!=sizeof(pcmWaveFormat)) {
return E_FAIL;
}
// 余分なBYTEがある?
if (pcmWaveFormat.wf.wFormatTag==WAVE_FORMAT_PCM) {
m_pwfx=(WAVEFORMATEX*)new CHAR[sizeof(WAVEFORMATEX)];
if (NULL==m_pwfx) {
return E_FAIL;
}
// waveformatexコピー
memcpy(m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat));
m_pwfx->cbSize=0;
}
else {
// 余分なBYTE読み込み
WORD cbExtraBytes=0L;
if (mmioRead(m_hmmio, (CHAR*)&cbExtraBytes, sizeof(WORD))!=sizeof(WORD)) {
return E_FAIL;
}
m_pwfx=(WAVEFORMATEX*)new CHAR[sizeof(WAVEFORMATEX)+cbExtraBytes];
if (NULL==m_pwfx) {
return E_FAIL;
}
// waveformatexコピー
memcpy(m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat));
m_pwfx->cbSize=cbExtraBytes;
// 余分なBYTE読み込み
if (mmioRead(m_hmmio, (CHAR*)(((BYTE*)&(m_pwfx->cbSize))+sizeof(WORD)), cbExtraBytes )!=cbExtraBytes) {
SAFE_DELETE(m_pwfx);
return E_FAIL;
}
}
// FMTチャンクから出る
if (0!=mmioAscend(m_hmmio, &ckIn, 0)) {
SAFE_DELETE(m_pwfx);
return E_FAIL;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// サイズ取得
DWORD CAudioWave::GetSize()
{
return m_dwSize;
}
//-----------------------------------------------------------------------------
// ファイルリセット
HRESULT CAudioWave::ResetFile()
{
if (m_hmmio==NULL) {
return CO_E_NOTINITIALIZED;
}
// データ検索
if (-1==mmioSeek(m_hmmio, m_ckRiff.dwDataOffset+sizeof(FOURCC), SEEK_SET)) {
return E_FAIL;
}
// データチャンク検索
m_ck.ckid=mmioFOURCC('d', 'a', 't', 'a');
if (0!=mmioDescend(m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK)) {
return E_FAIL;
}
return S_OK;
}
//-----------------------------------------------------------------------------
// ファイルから読み込み
HRESULT CAudioWave::Read(BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead)
{
MMIOINFO mmioinfoIn;
if (m_hmmio==NULL) {
return CO_E_NOTINITIALIZED;
}
if (pBuffer==NULL || pdwSizeRead==NULL) {
return E_INVALIDARG;
}
*pdwSizeRead=0;
if (0!=mmioGetInfo(m_hmmio, &mmioinfoIn, 0)) {
return E_FAIL;
}
UINT cbDataIn=dwSizeToRead;
if (cbDataIn>m_ck.cksize) {
cbDataIn=m_ck.cksize;
}
m_ck.cksize-=cbDataIn;
for (DWORD cT=0; cT<cbDataIn; cT++) {
// BYTEコピー
if (mmioinfoIn.pchNext==mmioinfoIn.pchEndRead) {
if (0!=mmioAdvance(m_hmmio, &mmioinfoIn, MMIO_READ)) {
return E_FAIL;
}
if (mmioinfoIn.pchNext==mmioinfoIn.pchEndRead) {
return E_FAIL;
}
}
// コピー
*((BYTE*)pBuffer+cT)=*((BYTE*)mmioinfoIn.pchNext);
mmioinfoIn.pchNext++;
}
if (0!=mmioSetInfo(m_hmmio, &mmioinfoIn, 0)) {
return E_FAIL;
}
*pdwSizeRead=cbDataIn;
return S_OK;
}
//-----------------------------------------------------------------------------
// ファイルを閉じる
HRESULT CAudioWave::Close()
{
mmioClose(m_hmmio, 0);
m_hmmio=NULL;
SAFE_DELETE_ARRAY(m_pResourceBuffer);
return S_OK;
}