-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSound.cpp
207 lines (181 loc) · 5.94 KB
/
Sound.cpp
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
#include "Global.h"
Sound::Sound(string filename) :Filename(filename), wfx({ 0 }), buffer({ 0 })
{
//Open File
if FAILED(errorcode = OpenFile())
{
OutputDebugStringA("Failed to Open File\n");
}
DWORD dwChunkSize;
DWORD dwChunkPosition;
DWORD filetype;
//check the file type, should be fourccWAVE or 'XWMA'
//Locating RIFF chunk
if FAILED(errorcode = FindChunk(hFile, fourccRIFF, dwChunkSize, dwChunkPosition))
{
OutputDebugStringA("Failed to Find RIFF\n");
}
//Identifying FileType
if FAILED(errorcode = ReadChunkData(hFile, &filetype, sizeof(DWORD), dwChunkPosition))
{
OutputDebugStringA("Failed to Read RIFF filetype\n");
}
if FAILED(errorcode = ReadChunkData(hFile, &filetype, sizeof(DWORD), dwChunkPosition))
{
OutputDebugStringA("Failed to Read RIFF filetype\n");
}
if (filetype != fourccWAVE)
{
OutputDebugStringA("Wrong FileType\n");
}
//Locating FMT chunk
errorcode = FindChunk(hFile, fourccFMT, dwChunkSize, dwChunkPosition);
if FAILED(errorcode)
{
OutputDebugStringA("Failed to Find FMT\n");
}
errorcode = ReadChunkData(hFile, &wfx, dwChunkSize, dwChunkPosition);
if FAILED(errorcode)
{
OutputDebugStringA("Failed to Read FMT ChunkSize\n");
}
//fill out the audio data buffer with the contents of the fourccDATA chunk
errorcode = FindChunk(hFile, fourccDATA, dwChunkSize, dwChunkPosition);
if FAILED(errorcode)
{
OutputDebugStringA("Failed to Find Data\n");
}
//Locating Audio Data
BYTE* pDataBuffer = new BYTE[dwChunkSize];
errorcode = ReadChunkData(hFile, pDataBuffer, dwChunkSize, dwChunkPosition);
if FAILED(errorcode)
{
OutputDebugStringA("Failed to Read Data\n");
}
//Populate Buffer
buffer.AudioBytes = dwChunkSize; //size of the audio buffer in bytes
if (buffer.AudioBytes == 0)
{
OutputDebugStringA("Audio Data is 0\n");
}
buffer.pAudioData = pDataBuffer; //buffer containing audio data
buffer.Flags = 0; // tell the source voice not to expect any data after this buffer
}
HRESULT Sound::OpenFile()
{
// Open the file
hFile = CreateFile(
Filename.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
OutputDebugStringA("hFile failed\n");
return HRESULT_FROM_WIN32(GetLastError());
}
if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, 0, NULL, FILE_BEGIN))
{
OutputDebugStringA("hFile failed\n");
return HRESULT_FROM_WIN32(GetLastError());
}
return S_OK;
}
Sound::~Sound()
{
}
HANDLE Sound::GetFile()
{
return hFile;
}
HRESULT Sound::FindChunk(HANDLE& hFile, DWORD fourcc, DWORD& dwChunkSize, DWORD& dwChunkDataPosition)
{
DWORD dwChunkType;
DWORD dwChunkDataSize;
DWORD dwRIFFDataSize = 0;
DWORD dwFileType;
DWORD bytesRead = 0;
DWORD dwOffset = 0;
HRESULT hr = S_OK;
/*
SetFilePointer Takes a File Handle,
The number of bytes to move the file pointer,
starting position of file pointer
*/
if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, 0, NULL, FILE_BEGIN))
return HRESULT_FROM_WIN32(GetLastError());
while (hr == S_OK)
{
/*
WAV file is arranged with ChunkID first then ChunkSize
dwChunkType is a buffer that receives the chunkID for the first 4 bytes
dwRead Receives the number of bytes read
dwChunkSize receives the ChunkDataSize for the next 4 bytes
*/
DWORD dwRead;
if (0 == ReadFile(hFile, &dwChunkType, sizeof(DWORD), &dwRead, NULL))
hr = HRESULT_FROM_WIN32(GetLastError());
if (0 == ReadFile(hFile, &dwChunkDataSize, sizeof(DWORD), &dwRead, NULL))
hr = HRESULT_FROM_WIN32(GetLastError());
/*
Check the ChunkType that was read
We could be looking for the data/format/RIFF
*/
switch (dwChunkType)
{
/*
Store the FileFormat (WAVE) in dwFileType if ChunkType is fourccRIFF
If not, Move File Pointer foward by 4 Bytes
*/
case fourccRIFF:
dwRIFFDataSize = dwChunkDataSize;
dwChunkDataSize = 4;
if (0 == ReadFile(hFile, &dwFileType, sizeof(DWORD), &dwRead, NULL))
hr = HRESULT_FROM_WIN32(GetLastError());
break;
default:
/*
Move File Pointer by ChunkDataSize to the next SubChunk
*/
if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, dwChunkDataSize, NULL, FILE_CURRENT))
return HRESULT_FROM_WIN32(GetLastError());
}
/*
Read ChunkID and ChunkSize which offsets by total of 8 Bytes (4 Bytes Each)
*/
dwOffset += sizeof(DWORD) * 2;
/*
Found the chunkType specified by User
*/
if (dwChunkType == fourcc)
{
dwChunkSize = dwChunkDataSize;
dwChunkDataPosition = dwOffset;
return S_OK;
}
/*
Set dwOffset to the next SubChunk
*/
dwOffset += dwChunkDataSize;
/*
Checking if dwRIFFDataSize is 0 or smaller,
Suggesting there is a problem with the file Chunks
*/
if (bytesRead >= dwRIFFDataSize) return S_FALSE;
}
//if cannot find chunk, return S_False;
return S_FALSE;
}
HRESULT Sound::ReadChunkData(HANDLE& hFile, void* buffer, DWORD buffersize, DWORD bufferoffset)
{
HRESULT hr = S_OK;
if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, bufferoffset, NULL, FILE_BEGIN))
return HRESULT_FROM_WIN32(GetLastError());
DWORD dwRead;
if (0 == ReadFile(hFile, buffer, buffersize, &dwRead, NULL))
hr = HRESULT_FROM_WIN32(GetLastError());
return hr;
}