続きです。今回は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; }