C++によるWAVEの読み込み

DirectXで音を鳴らしたくていろいろ調べてるのですが、
みなさんMMIO系の関数を使って読み込んでいましたが、
音を愛する僕がそんな便利なものに頼っていいのかと悩んだ末に
自力で読み込んでみることにしました。

```c++:WAVE.h
#include <vector>
#include <string>
class WAVE
{
public:
   // コンストラクタ
   WAVE();
   // デストラクタ
   ~WAVE();
   // 代入
   void operator=(const WAVE& wave);

   // チャンネル数
   int channel;
   // サンプリング周波数
   int sample;
   // 量子化ビット数
   int bit;
   // 時間
   int length;
   // 音楽データ・モノラル
   std::vector<double>monaural;
   // 音楽データ・ステレオ
   std::vector <std::vector<double>>stereo;
};

// 名前空間指定
namespace sound {
   // 文字確認
   int CheckChar(unsigned char* data, int dataSize, const std::string& find);
   // モノラル・8ビット
   void LoadMonaural8(WAVE& wave, FILE* file);
   // モノラル・16ビット
   void LoadMonaural16(WAVE& wave, FILE* file);
   // ステレオ・8ビット
   void LoadStereo8(WAVE& wave, FILE* file);
   // ステレオ・16ビット
   void LoadStereo16(WAVE& wave, FILE* file);
   // WAVEの読み込み
   int LoadWave(const std::string& fileName, WAVE& wave);
}
```

```c++:WAVE.cpp
#define _USE_MATH_DEFINES
#include "WAVE.h"
#include <iostream>
#include <math.h>

// チャンクIDサイズの最大
#define ID_MAX 4
// オーバーフローの防止
#define OVERFLLOW 32768.0

// RIFFチャンク
struct RIFF {
   //チャンクID
   unsigned char chunkID[ID_MAX];
   //チャンクサイズ
   unsigned long chunkSize;
   //フォーマットタイプ
   unsigned char chunkFormatType[ID_MAX];
};
// FMTチャンク
struct FMT {
   //チャンクID
   unsigned char chunkID[ID_MAX];
   //チャンクサイズ
   unsigned long chunkSize;
   //フォーマットタイプ
   unsigned short waveFormatType;
   //フォーマットチャンネル
   unsigned short formatChannel;
   //サンプリング周波数
   unsigned long samplesPerSec;
   //ビットレート
   unsigned long bytesPerSec;
   //ブロックサイズ
   unsigned short blockSize;
   //量子化ビット数
   unsigned short bitsPerSample;
};
// DATAチャンク
struct DATA {
   //チャンクID
   std::string chunkID;
   //チャンクサイズ
   unsigned long chunkSize;
};
// 8ビットステレオデータ
struct Sample8 {
   //左
   unsigned char left;
   //右
   unsigned char right;
};
// 16ビットステレオデータ
struct Sample16 {
   //左
   short left;
   //右
   short right;
};

// コンストラクタ
WAVE::WAVE()
{
}
// デストラクタ
WAVE::~WAVE()
{
}
// 代入
void WAVE::operator=(const WAVE & wave)
{
   channel  = wave.channel;
   sample   = wave.sample;
   bit      = wave.bit;
   length   = wave.length;
   monaural = wave.monaural;
   stereo   = wave.stereo;
}
// 文字確認
int sound::CheckChar(unsigned char * data, int dataSize, const std::string & find)
{
   for (unsigned int i = 0; i < find.size(); ++i)
   {
      for (int d = 0; d < dataSize; ++d)
      {
         if (data[d] == find[i])
         {
            break;
         }
         else
         {
            //文字確認失敗
            if (d >= dataSize - 1)
            {
               return -1;
            }
         }
      }
   }

   return 0;
}
// モノラル・8ビット
void sound::LoadMonaural8(WAVE & wave, FILE * file)
{
   wave.monaural.resize(wave.length);

   unsigned char data = 0;
   for (int i = 0; i < wave.length; ++i)
   {
      fread(&data, sizeof(data), 1, file);
      wave.monaural[i] = static_cast<double>(data);
   }
}
// モノラル・16ビット
void sound::LoadMonaural16(WAVE & wave, FILE * file)
{
   wave.monaural.resize(wave.length);

   short data = 0;
   for (int i = 0; i < wave.length; ++i)
   {
      fread(&data, sizeof(data), 1, file);
      /* 音データを-1以上1未満の範囲に正規化する */
      wave.monaural[i] = static_cast<double>(data) / OVERFLLOW;
   }
}
// ステレオ・8ビット
void sound::LoadStereo8(WAVE & wave, FILE * file)
{
   wave.stereo.resize(wave.channel);
   for (auto& w : wave.stereo)
   {
      w.resize(wave.length);
   }

   Sample8 data = {};
   for (int i = 0; i < wave.length; ++i)
   {
      fread(&data, sizeof(data), 1, file);
      wave.stereo[0][i] = static_cast<double>(data.left);
      wave.stereo[1][i] = static_cast<double>(data.right);
   }
}
// ステレオ・16ビット
void sound::LoadStereo16(WAVE & wave, FILE * file)
{
   wave.stereo.resize(wave.channel);
   for (auto& w : wave.stereo)
   {
      w.resize(wave.length);
   }
   
   Sample16 data = {};
   for (int i = 0; i < wave.length; ++i)
   {
      fread(&data, sizeof(data), 1, file);
      /* 音データを-1以上1未満の範囲に正規化する */
      wave.stereo[0][i] = static_cast<double>(data.left) / OVERFLLOW;
      wave.stereo[1][i] = static_cast<double>(data.right) / OVERFLLOW;
   }
}
// WAVEの読み込み
int sound::LoadWave(const std::string & fileName, WAVE & wave)
{
   FILE* file = nullptr;

   //ファイルオープン
   if (fopen_s(&file, fileName.c_str(), "rb") != 0)
   {
      return -1;
   }

   //チャンク宣言
   RIFF riff = {};
   FMT fmt = {};
   DATA data = {};

   //RIFF読み込み
   fread(&riff.chunkID[0], sizeof(riff.chunkID), 1, file);
   if (CheckChar(riff.chunkID, ID_MAX, "RIFF") != 0)
   {
      fclose(file);
      return -1;
   }
   fread(&riff.chunkSize, sizeof(riff.chunkSize), 1, file);
   fread(&riff.chunkFormatType[0], sizeof(riff.chunkFormatType), 1, file);
   if (CheckChar(riff.chunkFormatType, ID_MAX, "WAVE") != 0)
   {
      fclose(file);
      return -1;
   }

   //FMT読み込み
   fread(&fmt.chunkID[0], sizeof(fmt.chunkID), 1, file);
   if (CheckChar(fmt.chunkID, ID_MAX, "fmt ") != 0)
   {
      fclose(file);
      return -1;
   }
   fread(&fmt.chunkSize, sizeof(fmt.chunkSize), 1, file);
   fread(&fmt.waveFormatType, sizeof(fmt.waveFormatType), 1, file);
   fread(&fmt.formatChannel, sizeof(fmt.formatChannel), 1, file);
   fread(&fmt.samplesPerSec, sizeof(fmt.samplesPerSec), 1, file);
   fread(&fmt.bytesPerSec, sizeof(fmt.bytesPerSec), 1, file);
   fread(&fmt.blockSize, sizeof(fmt.blockSize), 1, file);
   fread(&fmt.bitsPerSample, sizeof(fmt.bitsPerSample), 1, file);
   //拡張部分
   std::vector<unsigned char>extended;
   extended.resize(fmt.chunkSize - (sizeof(fmt) - sizeof(fmt.chunkID) - sizeof(fmt.chunkSize)));
   if (extended.size() > 0)
   {
      fread(&extended[0], sizeof(unsigned char) * extended.size(), 1, file);
   }

   //ダミー宣言
   std::string chunkID;
   chunkID.resize(sizeof(unsigned char) * ID_MAX);
   //ID判別
   fread(&chunkID[0], sizeof(unsigned char) * ID_MAX, 1, file);

   //DATA以外の場合
   while (chunkID != "data")
   {
      //サイズ
      unsigned long size = 0;
      fread(&size, sizeof(size), 1, file);
      //データ
      std::vector<unsigned char>data;
      data.resize(size);
      fread(&data[0], sizeof(unsigned char) * size, 1, file);
      //ID
      fread(&chunkID[0], sizeof(unsigned char) * ID_MAX, 1, file);
   }

   //DATA読み込み
   data.chunkID = chunkID;
   fread(&data.chunkSize, sizeof(data.chunkSize), 1, file);

   wave.channel = fmt.formatChannel;
   wave.sample  = fmt.samplesPerSec;
   wave.bit     = fmt.bitsPerSample;
   wave.length  = data.chunkSize / fmt.blockSize;

   //モノラル
   if (fmt.formatChannel == 1)
   {
      //8ビット
      if (fmt.bitsPerSample == 8)
      {
         LoadMonaural8(wave, file);
      }
      //16ビット
      else if (fmt.bitsPerSample == 16)
      {
         LoadMonaural16(wave, file);
      }
   }
   //ステレオ
   else if (fmt.formatChannel == 2)
   {
      //8ビット
      if (fmt.bitsPerSample == 8)
      {
         LoadStereo8(wave, file);
      }
      //16ビット
      else if (fmt.bitsPerSample == 16)
      {
         LoadStereo16(wave, file);
      }
   }

   //ファイルクローズ
   fclose(file);

   return 0;
}
```

こんな感じで実装しました。
モノラル、ステレオの8bit、16bitに対応してます。
これらからDirectSoundや、XAudio2にデータを渡す方法で悩んでます。

もしよかったら、この読み込みについての改善点や
データの渡す方法などコメントで教えて頂ければありがたいです。