#pragma once #include #include //CCriticalSectionクラスを使用するため // CWaveOutクラス class CWaveOut : public CObject { public: //コンストラクタ CWaveOut(CWnd* pWndCallBack=NULL); //デストラクタ virtual ~CWaveOut(); //メンバー変数の初期化 void Init(); //WAVE出力デバイスの停止 void Delete(); //WAVE出力デバイスを使って演奏を開始します。 //timePerOut:一回に演奏する時間(_秒) BOOL Play(const WAVEFORMATEX* pwfxOut,UINT timePerOut); //演奏中かどうか? BOOL IsPlaying() const{return (m_hWaveOut!=NULL);}; //演奏を停止します。 void Stop(){Delete();}; //一時停止します。 BOOL Pause(); //一時停止中かどうか? BOOL IsPausing() const{return m_bPause;}; //派生クラスから音源ストリームを入力します。(オーバーライド) virtual UINT StreamIn(LPVOID pBuffer,UINT nBufSize){return FALSE;}; //WAVEFORMATEX構造体の取得 int GetOutFormat(LPWAVEFORMATEX pwfxOut=NULL) const; //WAVE出力デバイスに引き渡すWAVEFORMATEX構造体を設定します。 void SetOutFormat(const LPWAVEFORMATEX pwfxOut); //派生クラスから演奏位置を取得します。(オーバーライド) virtual UINT GetPos() const{return FALSE;}; //音量調節 //pBuffer:音源データが格納されているバッファ //nBufSize:バッファのバイト数 //pwfx:音源データの演奏形式を格納したWAVEFORMATEX構造体 BOOL DoVolume(LPVOID pBuffer,UINT nBufSize,WAVEFORMATEX* pwfx); //音量の設定 //LOWORD(dwVolume):左音量, HIWORD(dwVolume):右音量 void SetVolume(DWORD dwVolume){m_dwVolume=dwVolume;}; //音量の取得 //LOWORD(dwVolume):左音量, HIWORD(dwVolume):右音量 DWORD GetVolume() const{return m_dwVolume;}; //メンバー変数のm_byteInBuf(CByteArrayクラス)に格納された音源データを、 //モノラル→擬似ステレオ、ステレオ→モノラル変換して、引数のバッファに格納します。 // pBuffer:加工後の音源データを格納するバッファ // nBufSize:バッファのバイト数 // indexSample:現在の演奏位置(サンプル数) // validBytes:音源データの有効バイト数 // pwfx:音源データの演奏形式を格納したWAVEFORMATEX構造体 UINT DoStereo(LPVOID pBuffer,UINT nBufSize,UINT indexSample,UINT validBytes,WAVEFORMATEX* pwfxFile); public: //擬似ステレオ遅延時間の設定 void SetDelayStereo(int delay){m_nDelayStereo=delay;}; //擬似ステレオ遅延時間の取得 int GetDelayStereo() const{return m_nDelayStereo;}; protected: //音源データをファイルから読み込む BOOL ReadSampleData(PWAVEHDR pWaveHdr); //派生クラスから読み込み用のバッファサイズを取得します。(オーバーライド) //(オーバーライドしない場合のバッファサイズは、100_秒演奏するのに必要なサイズとします。) virtual UINT GetSizeOfLoadBuffer() const{return m_wfxOut.nAvgBytesPerSec*m_timePerOut/1000;}; //WAVE出力デバイスコールバック関数(スタティック関数) static void __stdcall StaticWaveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD_PTR dwInstance, DWORD dwParam1,DWORD dwParam2); //WAVE出力デバイスコールバック関数 void WaveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwParam1,DWORD dwParam2); //オーナーウィンドウにメッセージをポストします。(オーバーライド) virtual void PostMessage(UINT message,WPARAM wParam,LPARAM lParam); //他のスレッドと同期するために使用するCCriticalSectionクラス CCriticalSection m_key; WAVEFORMATEX m_wfxOut; //WAVEFORMATEX構造体 CWnd* m_pWndCallBack; //コールバックするCWndクラスへのポインタ HWAVEOUT m_hWaveOut; //WAVE出力デバイスのハンドル DWORD m_timePerOut; //一回に演奏する時間(_秒) CByteArray m_byteBuf1; //出力音源第一バッファ CByteArray m_byteBuf2; //出力音源第二バッファ WAVEHDR m_WaveHdr1; //第一バッファ用WAVEHDR構造体 WAVEHDR m_WaveHdr2; //第二バッファ用WAVEHDR構造体 BOOL m_bStop; //リセット時の2重呼び出しを避けるため BOOL m_bPause; //一時停止フラグ //ボリューム //LOWORD(dwVolume):左音量, HIWORD(dwVolume):右音量 DWORD m_dwVolume; //擬似ステレオ関連 CByteArray m_byteInBuf; //音源データ取り込み用バッファ CByteArray m_byteDelay; //遅延バッファ CByteArray m_byteCache; //演奏しなかった遅延時間に相当する遅延バッファの //残りの音源データを格納しておくバッファ int m_nDelayStereo; //ステレオ変換時の遅延時間(ms) }; //WAVEFORMATEX構造体の取得 inline int CWaveOut::GetOutFormat(LPWAVEFORMATEX pwfxOut/*=NULL*/) const { if (!::IsBadWritePtr(pwfxOut,sizeof(WAVEFORMATEX))) ::CopyMemory(pwfxOut,&m_wfxOut,sizeof(WAVEFORMATEX)); return sizeof(WAVEFORMATEX); } //WAVE出力デバイスに引き渡すWAVEFORMATEX構造体を設定します。 inline void CWaveOut::SetOutFormat(const LPWAVEFORMATEX pwfxOut) { //入力されたWAVEFORMATEX構造体が有効な場合。 if (!::IsBadReadPtr(pwfxOut,sizeof(WAVEFORMATEX))){ //WAVE出力デバイスを停止します。 Delete(); //入力されたWAVEFORMATEX構造体で再演奏します。 Play(pwfxOut,0); } } //オーナーウィンドウにメッセージをポストします。(オーバーライド) inline void CWaveOut::PostMessage(UINT message,WPARAM wParam,LPARAM lParam) { if (m_pWndCallBack) m_pWndCallBack->PostMessage(message,wParam,lParam); }