1 // helper module for xaudio2 tutorial from http://www.win32developer.com/tutorial/xaudio/xaudio_tutorial_1.shtm 2 module wave; 3 4 import core.stdc..string : memset, memcpy; 5 6 import std.conv; 7 import std.stdio; 8 9 import directx.com; 10 import directx.xaudio2; 11 12 13 struct Wave 14 { 15 private: 16 WAVEFORMATEX m_wf; 17 XAUDIO2_BUFFER m_xa; 18 ubyte[] m_waveData; 19 public: 20 this(string szFile) 21 { 22 // i don't like this calls, but let it be here for a moment 23 memset(&m_wf, 0, m_wf.sizeof); 24 memset(&m_xa, 0, m_xa.sizeof); 25 26 load(szFile); 27 } 28 const (XAUDIO2_BUFFER)* xaBuffer() {return &m_xa;} 29 30 const (WAVEFORMATEX)* wf() {return &m_wf;} 31 32 bool load(string szFile) { 33 34 auto file = File(szFile, "rb"); 35 36 // additional variables for some hacking 37 char[4] dwChunkId = 0; 38 char[4] dwExtra = 0; 39 byte[4] tmp; 40 DWORD dwFileSize = 0, dwChunkSize = 0; 41 42 file.seek(0); 43 file.rawRead(dwChunkId); 44 if( dwChunkId != "RIFF") 45 return false; 46 47 file.seek(4); 48 file.rawRead(tmp); 49 dwFileSize = *cast(DWORD*)tmp.ptr; 50 if(dwFileSize <= 16) 51 return false; 52 53 file.seek(8); 54 file.rawRead(dwExtra); 55 if(dwExtra != "WAVE") 56 { 57 file.close(); 58 return false; 59 } 60 61 //look for 'fmt ' chunk id 62 bool bFilledFormat = false; 63 64 // byte offset 12 is where the data starts 65 for(uint i = 12; i < dwFileSize; ) 66 { 67 file.seek(i); 68 file.rawRead(dwChunkId); 69 70 file.seek(i+4); 71 file.rawRead(tmp); 72 dwChunkSize = cast(DWORD)*tmp.ptr; 73 74 if(dwChunkId == "fmt ") 75 { 76 77 byte[WAVEFORMATEX.sizeof] wavetmp; 78 79 file.seek(i+8); 80 file.rawRead(wavetmp); 81 memcpy(&m_wf, wavetmp.ptr, WAVEFORMATEX.sizeof); 82 bFilledFormat = true; 83 break; 84 } 85 dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries 86 dwChunkSize += 1; 87 dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment 88 i += dwChunkSize; 89 } 90 if(!bFilledFormat) 91 { 92 file.close(); 93 return false; 94 } 95 96 //look for 'data' chunk id 97 bool bFilledData = false; 98 for(uint i = 12; i < dwFileSize; ) 99 { 100 file.seek(i); 101 file.rawRead(dwChunkId); 102 103 file.seek(i + 4); 104 file.rawRead(tmp); 105 dwChunkSize = *cast(DWORD*)tmp.ptr; 106 107 if(dwChunkId == "data") 108 { 109 m_waveData.length = dwChunkSize; 110 111 file.seek(i + 8); 112 file.rawRead(m_waveData); 113 114 m_xa.AudioBytes = dwChunkSize; 115 m_xa.pAudioData = m_waveData.ptr; 116 m_xa.PlayBegin = 0; 117 m_xa.PlayLength = 0; 118 bFilledData = true; 119 break; 120 } 121 dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries 122 dwChunkSize += 1; 123 dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment 124 i += dwChunkSize; 125 } 126 if(!bFilledData) 127 { 128 file.close(); 129 return false; 130 } 131 132 return true; 133 } 134 }