X operations(XOPS)に非常に近いFPSゲームを制作・リメイクし、成果物をオープンソースとして公開することを目的としたプロジェクトです。
| Revision | 252 (tree) |
|---|---|
| Time | 2020-10-12 19:46:02 |
| Author | |
DirectSoundにて、非3Dモノラル再生に対応(ezds.dll同等)、および24ビットPCMと32ビット浮動小数点数PCMに対応。
| @@ -31,12 +31,14 @@ | ||
| 31 | 31 | |
| 32 | 32 | #include "sound.h" |
| 33 | 33 | |
| 34 | -#ifdef SOUND_DIRECTSOUND | |
| 34 | +#if (SOUND_ENGINE == 1 || SOUND_ENGINE == 2) | |
| 35 | 35 | |
| 36 | 36 | //! @brief コンストラクタ |
| 37 | 37 | SoundControl::SoundControl() |
| 38 | 38 | { |
| 39 | 39 | pDSound = NULL; |
| 40 | + p3DListener = NULL; | |
| 41 | + mastervolume = 1.0f; | |
| 40 | 42 | } |
| 41 | 43 | |
| 42 | 44 | //! @brief ディストラクタ |
| @@ -166,9 +168,10 @@ | ||
| 166 | 168 | pwfex->cbSize = 0; |
| 167 | 169 | |
| 168 | 170 | //非対応フォーマットなら失敗 |
| 169 | - if( pwfex->wFormatTag != WAVE_FORMAT_PCM ){ return -1; } | |
| 171 | + if( (pwfex->wFormatTag != WAVE_FORMAT_PCM)&&(pwfex->wFormatTag != WAVE_FORMAT_IEEE_FLOAT) ){ return -1; } | |
| 170 | 172 | if( (pwfex->nChannels != 1)&&(pwfex->nChannels != 2) ){ return -1; } |
| 171 | - if( (pwfex->wBitsPerSample != 8)&&(pwfex->wBitsPerSample != 16) ){ return -1; } | |
| 173 | + if( (pwfex->wBitsPerSample != 8)&&(pwfex->wBitsPerSample != 16) | |
| 174 | + &&(pwfex->wBitsPerSample != 24)&&(pwfex->wBitsPerSample != 32) ){ return -1; } | |
| 172 | 175 | |
| 173 | 176 | //もしステレオデータなら |
| 174 | 177 | if( pwfex->nChannels == 2 ){ |
| @@ -266,6 +269,27 @@ | ||
| 266 | 269 | byte += 2; |
| 267 | 270 | } |
| 268 | 271 | } |
| 272 | + if( samplingbits == 24 ){ | |
| 273 | + int byte = 0; | |
| 274 | + for(int i=0; i<dwSize; i+=6){ | |
| 275 | + //ステレオデータなら、左側のデータだけ格納 | |
| 276 | + ((BYTE*)pBuffer)[byte+0] = (BYTE)pWavData[i + 0]; | |
| 277 | + ((BYTE*)pBuffer)[byte+1] = (BYTE)pWavData[i + 1]; | |
| 278 | + ((BYTE*)pBuffer)[byte+2] = (BYTE)pWavData[i + 2]; | |
| 279 | + byte += 3; | |
| 280 | + } | |
| 281 | + } | |
| 282 | + if( samplingbits == 32 ){ | |
| 283 | + int byte = 0; | |
| 284 | + for(int i=0; i<dwSize; i+=8){ | |
| 285 | + //ステレオデータなら、左側のデータだけ格納 | |
| 286 | + ((BYTE*)pBuffer)[byte+0] = (BYTE)pWavData[i + 0]; | |
| 287 | + ((BYTE*)pBuffer)[byte+1] = (BYTE)pWavData[i + 1]; | |
| 288 | + ((BYTE*)pBuffer)[byte+2] = (BYTE)pWavData[i + 2]; | |
| 289 | + ((BYTE*)pBuffer)[byte+3] = (BYTE)pWavData[i + 3]; | |
| 290 | + byte += 4; | |
| 291 | + } | |
| 292 | + } | |
| 269 | 293 | } |
| 270 | 294 | |
| 271 | 295 | //ロック解除 |
| @@ -350,6 +374,25 @@ | ||
| 350 | 374 | if( (id < 0)||(MAX_LOADSOUND -1 < id) ){ return 0; } |
| 351 | 375 | if( pDSBuffer[id][0] == NULL ){ return 0; } |
| 352 | 376 | |
| 377 | +#if SOUND_ENGINE == 1 | |
| 378 | + | |
| 379 | + if( volume < -100 ){ volume = -100; } | |
| 380 | + if( volume > 100 ){ volume = 100; } | |
| 381 | + | |
| 382 | + float dist; | |
| 383 | + int playvolume; | |
| 384 | + int pan = 0; | |
| 385 | + | |
| 386 | + //距離による再生音量決定 | |
| 387 | + if( CheckSourceDist(x, y, z, false, &dist) == false ){ | |
| 388 | + return 0; | |
| 389 | + } | |
| 390 | + playvolume = CalculationVolume(volume, dist, false); | |
| 391 | + | |
| 392 | + return PlaySound(id, playvolume, pan); | |
| 393 | + | |
| 394 | +#else //#if SOUND_ENGINE | |
| 395 | + | |
| 353 | 396 | DWORD status = 0; |
| 354 | 397 | |
| 355 | 398 | for(int i=0; i<MAX_SOUNDLISTS; i++){ |
| @@ -383,6 +426,8 @@ | ||
| 383 | 426 | } |
| 384 | 427 | |
| 385 | 428 | return 0; |
| 429 | + | |
| 430 | +#endif //#if SOUND_ENGINE | |
| 386 | 431 | } |
| 387 | 432 | |
| 388 | 433 | //! @brief 読み込み済みのサウンド数を取得 |
| @@ -466,7 +511,7 @@ | ||
| 466 | 511 | ckInfo.ckid = mmioFOURCC('f','m','t',' '); |
| 467 | 512 | if( mmioDescend(hMmio, &ckInfo, &riffckInfo, MMIO_FINDCHUNK) == MMSYSERR_NOERROR ){ |
| 468 | 513 | if( mmioRead(hMmio, (HPSTR) &pcmWaveFormat, sizeof(pcmWaveFormat)) == sizeof(pcmWaveFormat) ){ |
| 469 | - if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM ){ | |
| 514 | + if( (pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM)||(pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) ){ | |
| 470 | 515 | if( (pcmWaveFormat.wf.nChannels == 1)||(pcmWaveFormat.wf.nChannels == 2) ){ |
| 471 | 516 | *pwfex = new WAVEFORMATEX; |
| 472 | 517 | if( *pwfex != NULL ){ |
| @@ -515,4 +560,57 @@ | ||
| 515 | 560 | return retn; |
| 516 | 561 | } |
| 517 | 562 | |
| 518 | -#endif //SOUND_DIRECTSOUND | |
| \ No newline at end of file | ||
| 563 | +#if SOUND_ENGINE == 1 | |
| 564 | +//! @brief 音源との距離を調べる | |
| 565 | +//! @param x 音源のX座標 | |
| 566 | +//! @param y 音源のY座標 | |
| 567 | +//! @param z 音源のZ座標 | |
| 568 | +//! @param snear 近距離音源 | |
| 569 | +//! @param out_dist 距離 | |
| 570 | +//! @return 有効(内):true 無効(外):false | |
| 571 | +bool SoundControl::CheckSourceDist(float x, float y, float z, bool snear, float *out_dist) | |
| 572 | +{ | |
| 573 | + D3DXVECTOR3 camera; | |
| 574 | + float dx, dy, dz, dist; | |
| 575 | + int max_dist; | |
| 576 | + | |
| 577 | + p3DListener->GetPosition(&camera); | |
| 578 | + | |
| 579 | + if( snear == false ){ | |
| 580 | + max_dist = MAX_SOUNDDIST; | |
| 581 | + } | |
| 582 | + else{ | |
| 583 | + max_dist = 30; | |
| 584 | + } | |
| 585 | + | |
| 586 | + dx = camera.x - x; | |
| 587 | + dy = camera.y - y; | |
| 588 | + dz = camera.z - z; | |
| 589 | + dist = dx*dx + dy*dy + dz*dz; | |
| 590 | + if( dist > max_dist * max_dist ){ | |
| 591 | + *out_dist = 0.0f; | |
| 592 | + return false; | |
| 593 | + } | |
| 594 | + | |
| 595 | + *out_dist = sqrt(dist); | |
| 596 | + return true; | |
| 597 | +} | |
| 598 | + | |
| 599 | +//! @brief 音量を計算 | |
| 600 | +//! @param MaxVolume 音源の最大音量 | |
| 601 | +//! @param dist 音源との距離 | |
| 602 | +//! @param snear 近距離音源 | |
| 603 | +int SoundControl::CalculationVolume(int MaxVolume, float dist, bool snear) | |
| 604 | +{ | |
| 605 | + int max_dist; | |
| 606 | + if( snear == false ){ | |
| 607 | + max_dist = MAX_SOUNDDIST; | |
| 608 | + } | |
| 609 | + else{ | |
| 610 | + max_dist = 30; | |
| 611 | + } | |
| 612 | + return (int)( (float)MaxVolume/max_dist*dist*-1 + MaxVolume ); | |
| 613 | +} | |
| 614 | +#endif | |
| 615 | + | |
| 616 | +#endif //SOUND_ENGINE | |
| \ No newline at end of file |
| @@ -31,7 +31,7 @@ | ||
| 31 | 31 | |
| 32 | 32 | #include "sound.h" |
| 33 | 33 | |
| 34 | -#ifndef SOUND_DIRECTSOUND | |
| 34 | +#if SOUND_ENGINE == 0 | |
| 35 | 35 | |
| 36 | 36 | //! @brief コンストラクタ |
| 37 | 37 | SoundControl::SoundControl() |
| @@ -42,6 +42,8 @@ | ||
| 42 | 42 | for(int i=0; i<MAX_LOADSOUND; i++){ |
| 43 | 43 | useflag[i] = false; |
| 44 | 44 | } |
| 45 | + | |
| 46 | + mastervolume = 1.0f; | |
| 45 | 47 | } |
| 46 | 48 | |
| 47 | 49 | //! @brief ディストラクタ |
| @@ -337,4 +339,4 @@ | ||
| 337 | 339 | return (int)( (float)MaxVolume/max_dist*dist*-1 + MaxVolume ); |
| 338 | 340 | } |
| 339 | 341 | |
| 340 | -#endif //SOUND_DIRECTSOUND | |
| \ No newline at end of file | ||
| 342 | +#endif //SOUND_ENGINE | |
| \ No newline at end of file |
| @@ -42,25 +42,32 @@ | ||
| 42 | 42 | #include "main.h" |
| 43 | 43 | #include <windows.h> |
| 44 | 44 | |
| 45 | -//#define SOUND_DIRECTSOUND //!< @brief サウンドの再生ライブラリを選択 @details 定数宣言有効:DirectSound 定数宣言無効(コメント化):ezds.dll | |
| 45 | +#define SOUND_ENGINE 0 //!< @brief サウンドの再生ライブラリを選択 @details ezds.dll:0 DirectSound(2D再生):1 DirectSound(3D再生):2 | |
| 46 | 46 | |
| 47 | -#ifdef SOUND_DIRECTSOUND | |
| 47 | +#if SOUND_ENGINE == 0 | |
| 48 | + typedef int (*FARPROCH)(HWND); //!< DLL Parameter | |
| 49 | + typedef int (*FARPROCCI)(char*, int); //!< DLL Parameter | |
| 50 | + typedef int (*FARPROCIII)(int, int, int); //!< DLL Parameter | |
| 51 | + typedef int (*FARPROCI)(int); //!< DLL Parameter | |
| 52 | + | |
| 53 | + #define SOUND_CORE "ezds" //!< バージョン表示用情報 | |
| 54 | +#else //#if SOUND_ENGINE | |
| 48 | 55 | #include <dsound.h> |
| 49 | 56 | #include <mmsystem.h> |
| 50 | 57 | #pragma comment(lib, "dsound.lib") |
| 51 | 58 | #pragma comment(lib, "dxguid.lib") |
| 52 | 59 | #pragma comment(lib, "winmm.lib") |
| 60 | + #ifndef WAVE_FORMAT_IEEE_FLOAT | |
| 61 | + #define WAVE_FORMAT_IEEE_FLOAT 3 | |
| 62 | + #endif | |
| 53 | 63 | |
| 54 | - #define SOUND_CORE "DirectSound" //!< バージョン表示用情報 | |
| 55 | -#else //#ifdef SOUND_DIRECTSOUND | |
| 56 | - typedef int (*FARPROCH)(HWND); //!< DLL Parameter | |
| 57 | - typedef int (*FARPROCCI)(char*, int); //!< DLL Parameter | |
| 58 | - typedef int (*FARPROCIII)(int, int, int); //!< DLL Parameter | |
| 59 | - typedef int (*FARPROCI)(int); //!< DLL Parameter | |
| 64 | + #if SOUND_ENGINE == 1 | |
| 65 | + #define SOUND_CORE "DirectSound(Monaural)" //!< バージョン表示用情報 | |
| 66 | + #else | |
| 67 | + #define SOUND_CORE "DirectSound(Stereo)" //!< バージョン表示用情報 | |
| 68 | + #endif | |
| 69 | +#endif //#if SOUND_ENGINE | |
| 60 | 70 | |
| 61 | - #define SOUND_CORE "ezds" //!< バージョン表示用情報 | |
| 62 | -#endif //#ifdef SOUND_DIRECTSOUND | |
| 63 | - | |
| 64 | 71 | //! @brief サウンドを再生するクラス |
| 65 | 72 | //! @details サウンドの読み込みから再生までを管理します。 |
| 66 | 73 | //! @details 内部では ezds.dll を呼び出して使用しています。 |
| @@ -67,28 +74,7 @@ | ||
| 67 | 74 | //! @details 参考資料:「みかん箱」http://mikan.the-ninja.jp/ ⇒ 技術資料 ⇒ ezds.dllファイル解析資料 |
| 68 | 75 | class SoundControl |
| 69 | 76 | { |
| 70 | -#ifdef SOUND_DIRECTSOUND | |
| 71 | - LPDIRECTSOUND8 pDSound; //!< DIRECTSOUND8のポインタ | |
| 72 | - LPDIRECTSOUNDBUFFER pDSBuffer[MAX_LOADSOUND][MAX_SOUNDLISTS]; //!< セカンダリーバッファー | |
| 73 | - LPDIRECTSOUND3DLISTENER8 p3DListener; //!< リスナー | |
| 74 | - float mastervolume; //!< 音量 | |
| 75 | - | |
| 76 | - bool CheckSoundFile(char* filename, int *filesize, int *fileoffset, WAVEFORMATEX** pwfex); | |
| 77 | - int GetDSVolume(int volume); | |
| 78 | - | |
| 79 | -public: | |
| 80 | - SoundControl(); | |
| 81 | - ~SoundControl(); | |
| 82 | - int InitSound(WindowControl *WindowCtrl); | |
| 83 | - void DestroySound(); | |
| 84 | - void SetVolume(float volume); | |
| 85 | - void SetCamera(float x, float y, float z, float rx); | |
| 86 | - int LoadSound(char* filename); | |
| 87 | - int PlaySound(int id, int volume, int pan); | |
| 88 | - int Play3DSound(int id, float x, float y, float z, int volume); | |
| 89 | - void CleanupSound(int id); | |
| 90 | - int GetTotalSounds(); | |
| 91 | -#else //#ifdef SOUND_DIRECTSOUND | |
| 77 | +#if SOUND_ENGINE == 0 | |
| 92 | 78 | HINSTANCE lib; //!< DLLファイルのインスタンス |
| 93 | 79 | FARPROC DSver; //!< DSver() |
| 94 | 80 | FARPROCH DSinit; //!< DSinit() |
| @@ -107,7 +93,20 @@ | ||
| 107 | 93 | |
| 108 | 94 | bool CheckSourceDist(float x, float y, float z, bool near, float *out_dist); |
| 109 | 95 | int CalculationVolume(int MaxVolume, float dist, bool near); |
| 96 | +#else //#if SOUND_ENGINE | |
| 97 | + LPDIRECTSOUND8 pDSound; //!< DIRECTSOUND8のポインタ | |
| 98 | + LPDIRECTSOUNDBUFFER pDSBuffer[MAX_LOADSOUND][MAX_SOUNDLISTS]; //!< セカンダリーバッファー | |
| 99 | + LPDIRECTSOUND3DLISTENER8 p3DListener; //!< リスナー | |
| 100 | + float mastervolume; //!< 音量 | |
| 110 | 101 | |
| 102 | + bool CheckSoundFile(char* filename, int *filesize, int *fileoffset, WAVEFORMATEX** pwfex); | |
| 103 | + int GetDSVolume(int volume); | |
| 104 | +#if SOUND_ENGINE == 1 | |
| 105 | + bool CheckSourceDist(float x, float y, float z, bool near, float *out_dist); | |
| 106 | + int CalculationVolume(int MaxVolume, float dist, bool near); | |
| 107 | +#endif | |
| 108 | +#endif //#if SOUND_ENGINE | |
| 109 | + | |
| 111 | 110 | public: |
| 112 | 111 | SoundControl(); |
| 113 | 112 | ~SoundControl(); |
| @@ -120,7 +119,6 @@ | ||
| 120 | 119 | int Play3DSound(int id, float x, float y, float z, int volume); |
| 121 | 120 | int GetTotalSounds(); |
| 122 | 121 | void CleanupSound(int id); |
| 123 | -#endif //#ifdef SOUND_DIRECTSOUND | |
| 124 | 122 | }; |
| 125 | 123 | |
| 126 | 124 | #endif |
| \ No newline at end of file |