forked from abartlett139/Omni
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WAVE.h
137 lines (126 loc) · 3.31 KB
/
WAVE.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef WAVE_H
#define WAVE_H
#include <xaudio2.h>
#include <fstream>
#include <vector>
class Wave
{
private:
WAVEFORMATEX m_wf;
XAUDIO2_BUFFER m_xa;
BYTE* m_waveData;
public:
Wave(const char* szFile = NULL) : m_waveData(NULL) {
ZeroMemory(&m_wf, sizeof(m_wf));
ZeroMemory(&m_xa, sizeof(m_xa));
load(szFile);
}
Wave(const Wave& c) : m_waveData(NULL) {
m_wf = c.m_wf;
m_xa = c.m_xa;
if (c.m_waveData)
{
m_waveData = new BYTE[m_xa.AudioBytes];
memcpy(m_waveData, c.m_waveData, m_xa.AudioBytes);
m_xa.pAudioData = m_waveData;
}
}
~Wave() {
if (m_waveData)
delete[] m_waveData;
m_waveData = NULL;
}
void setToLoop() {
m_xa.LoopCount = XAUDIO2_LOOP_INFINITE;
}
const XAUDIO2_BUFFER* xaBuffer() const { return &m_xa; }
const WAVEFORMATEX* wf() const { return &m_wf; }
bool load(const char* szFile) {
if (szFile == NULL)
return false;
std::ifstream inFile(szFile, std::ios::binary | std::ios::in);
if (inFile.bad())
return false;
DWORD dwChunkId = 0, dwFileSize = 0, dwChunkSize = 0, dwExtra = 0;
//look for 'RIFF' chunk identifier
inFile.seekg(0, std::ios::beg);
inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
if (dwChunkId != 'FFIR')
{
inFile.close();
return false;
}
inFile.seekg(4, std::ios::beg); //get file size
inFile.read(reinterpret_cast<char*>(&dwFileSize), sizeof(dwFileSize));
if (dwFileSize <= 16)
{
inFile.close();
return false;
}
inFile.seekg(8, std::ios::beg); //get file format
inFile.read(reinterpret_cast<char*>(&dwExtra), sizeof(dwExtra));
if (dwExtra != 'EVAW')
{
inFile.close();
return false;
}
//look for 'fmt ' chunk id
bool bFilledFormat = false;
for (unsigned int i = 12; i < dwFileSize; )
{
inFile.seekg(i, std::ios::beg);
inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
inFile.seekg(i + 4, std::ios::beg);
inFile.read(reinterpret_cast<char*>(&dwChunkSize), sizeof(dwChunkSize));
if (dwChunkId == ' tmf')
{
inFile.seekg(i + 8, std::ios::beg);
inFile.read(reinterpret_cast<char*>(&m_wf), sizeof(m_wf));
bFilledFormat = true;
break;
}
dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries
dwChunkSize += 1;
dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment
i += dwChunkSize;
}
if (!bFilledFormat)
{
inFile.close();
return false;
}
//look for 'data' chunk id
bool bFilledData = false;
for (unsigned int i = 12; i < dwFileSize; )
{
inFile.seekg(i, std::ios::beg);
inFile.read(reinterpret_cast<char*>(&dwChunkId), sizeof(dwChunkId));
inFile.seekg(i + 4, std::ios::beg);
inFile.read(reinterpret_cast<char*>(&dwChunkSize), sizeof(dwChunkSize));
if (dwChunkId == 'atad')
{
m_waveData = new BYTE[dwChunkSize];
inFile.seekg(i + 8, std::ios::beg);
inFile.read(reinterpret_cast<char*>(m_waveData), dwChunkSize);
m_xa.AudioBytes = dwChunkSize;
m_xa.pAudioData = m_waveData;
m_xa.PlayBegin = 0;
m_xa.PlayLength = 0;
bFilledData = true;
break;
}
dwChunkSize += 8; //add offsets of the chunk id, and chunk size data entries
dwChunkSize += 1;
dwChunkSize &= 0xfffffffe; //guarantees WORD padding alignment
i += dwChunkSize;
}
if (!bFilledData)
{
inFile.close();
return false;
}
inFile.close();
return true;
}
};
#endif