ゲーム開発32:XAudio2でWaveを再生する2

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

コメントを残す

メールアドレスが公開されることはありません。