-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathwave.cpp
More file actions
270 lines (222 loc) · 8.29 KB
/
Copy pathwave.cpp
File metadata and controls
270 lines (222 loc) · 8.29 KB
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
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
/*****************************************************************
*
* Copyright (c) 1996 Microsoft Corporation
*
* File: wave.cpp
* Content: Routines for getting waves from resources
* Author: Dave Edson; modified by Peter Donnelly
*
******************************************************************/
#include <windows.h>
#include "wave.h"
typedef struct tagWAVEFILE
{
DWORD cbSize; // Size of file
LPWAVEFORMATEX pwfxInfo; // Wave Header
LPBYTE pbData; // Wave Bits
}
WAVEFILE, *LPWAVEFILE;
// Function Prototypes
BOOL wave_ParseWaveMemory(void *pvRes,
WAVEFORMATEX **ppWaveHeader,
BYTE **ppbWaveData,
DWORD *pcbWaveSize);
/////////////////////////////////////////////////////////////////
//
// WAVE_LoadResource: Gets a wave file into the memory pointed
// to by pWaveFile from a resource.
//
/////////////////////////////////////////////////////////////////
LPVOID WAVE_LoadResource
(int ID, // ID of resource
HMODULE hModule, // hInst of app with WAVE
LPWAVEFILE pWaveFile) // Points to the struct to fill
{
HRSRC hResInfo;
HGLOBAL hResData;
void *pvRes;
DWORD dwSize;
LPVOID lpMemory;
// Find the resource and load into memory
if (((hResInfo = FindResourceA(hModule, MAKEINTRESOURCEA(ID), "WAVE")) != NULL) &&
((hResData = LoadResource(hModule, hResInfo)) != NULL) &&
((pvRes = LockResource(hResData)) != NULL))
{
// If we found it, copy the bits from the resource into
// our own chunk of memory
dwSize = SizeofResource(hModule, hResInfo);
lpMemory = malloc (dwSize);
memcpy (lpMemory, pvRes, dwSize);
UnlockResource(hResData);
FreeResource(hResData);
// Parse it out
if (wave_ParseWaveMemory(lpMemory,
&(pWaveFile->pwfxInfo),
&(pWaveFile->pbData),
&(pWaveFile->cbSize)))
{
return lpMemory; // OK
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////
//
// wave_ParseWaveMemory
// Parses a chunk of memory into the header and samples.
// This is done by looking for the "fmt " and "data"
// fields in the memory.
//
//////////////////////////////////////////////////////////////////
BOOL wave_ParseWaveMemory
(LPVOID lpChunkOfMemory, // Points to raw ram
LPWAVEFORMATEX *lplpWaveHeader, // Points to pointer to header
LPBYTE *lplpWaveSamples,// Points to pointer to samples
LPDWORD lpcbWaveSize) // Points to size
{
LPDWORD pdw;
LPDWORD pdwEnd;
DWORD dwRiff;
DWORD dwType;
DWORD dwLength;
// Set defaults to NULL or zero
if (lplpWaveHeader)
*lplpWaveHeader = NULL;
if (lplpWaveSamples)
*lplpWaveSamples = NULL;
if (lpcbWaveSize)
*lpcbWaveSize = 0;
// Set up DWORD pointers to the start of the chunk
// of memory.
pdw = (DWORD *)lpChunkOfMemory;
// Get the type and length of the chunk of memory
dwRiff = *pdw++;
dwLength = *pdw++;
dwType = *pdw++;
// Using the mmioFOURCC macro (part of Windows SDK), ensure
// that this is a RIFF WAVE chunk of memory
if (dwRiff != mmioFOURCC('R', 'I', 'F', 'F'))
return FALSE; // not even RIFF
if (dwType != mmioFOURCC('W', 'A', 'V', 'E'))
return FALSE; // not a WAV
// Find the pointer to the end of the chunk of memory
pdwEnd = (DWORD *)((BYTE *)pdw + dwLength-4);
// Run through the bytes looking for the tags
while (pdw < pdwEnd)
{
dwType = *pdw++;
dwLength = *pdw++;
switch (dwType)
{
// Found the format part
case mmioFOURCC('f', 'm', 't', ' '):
if (lplpWaveHeader && !*lplpWaveHeader)
{
if (dwLength < sizeof(WAVEFORMAT))
return FALSE; // something's wrong! Not a WAV
// Set the lplpWaveHeader to point to this part of
// the memory chunk
*lplpWaveHeader = (LPWAVEFORMATEX)pdw;
// Check to see if the other two items have been
// filled out yet (the bits and the size of the
// bits). If so, then this chunk of memory has
// been parsed out and we can exit
if ((!lplpWaveSamples || *lplpWaveSamples) &&
(!lpcbWaveSize || *lpcbWaveSize))
{
return TRUE;
}
}
break;
// Found the samples
case mmioFOURCC('d', 'a', 't', 'a'):
if ((lplpWaveSamples && !*lplpWaveSamples) ||
(lpcbWaveSize && !*lpcbWaveSize))
{
// Point the samples pointer to this part of the
// chunk of memory.
if (lplpWaveSamples) *lplpWaveSamples = (LPBYTE)pdw;
// Set the size of the wave
if (lpcbWaveSize) *lpcbWaveSize = dwLength;
// Make sure we have our header pointer set up.
// If we do, we can exit
if (!lplpWaveHeader || *lplpWaveHeader)
return TRUE;
}
break;
} // End case
// Move the pointer through the chunk of memory
pdw = (DWORD *)((BYTE *)pdw + ((dwLength+1)&~1));
}
// Failed! If we made it here, we did not get all the pieces
// of the wave
return FALSE;
} // wave_ParseWaveMemory
//////////////////////////////////////////////////////////////////
//
// LoadWave
// Gets the sound data and loads it into a DirectSound
// secondary buffer.
//
//
//////////////////////////////////////////////////////////////////
void LoadWave(HINSTANCE hinst, int ResourceID,
LPDIRECTSOUND lpds,
LPDIRECTSOUNDBUFFER &lpDSB)
{
// These variables are used in Steps 1 and 2
LPVOID lpWaveData;
WAVEFILE WaveFile;
DSBUFFERDESC dsbd;
// These variables are used in step 3, further down below
LPVOID pbData = NULL;
LPVOID pbData2 = NULL;
DWORD dwLength;
DWORD dwLength2;
lpWaveData = WAVE_LoadResource (ResourceID, hinst, &WaveFile );
// Step 1: Set up the direct sound buffer.
memset(&dsbd, 0, sizeof(DSBUFFERDESC));
dsbd.dwSize = sizeof(DSBUFFERDESC);
// We want a buffer that lives on the sound card's memory
// (DSBCAPS_STATIC) and can have the pan, volume, and
// frequency adjusted (DSBCAPS_CTRLDEFAULT)
dsbd.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_STATIC ;
// Set up the size and format
dsbd.dwBufferBytes = WaveFile.cbSize;
dsbd.lpwfxFormat = WaveFile.pwfxInfo; // Must be a PCM format!
// Step 2: Create the buffer
if (DS_OK != lpds->CreateSoundBuffer(&dsbd, &lpDSB, NULL))
{
OutputDebugStringA("Failed to create sound buffer\n");
return;
}
// Once this code succeeds, lpDSB will point to a DirectSoundBuffer.
// At this point, you can copy blocks of sound data into the buffer,
// using the Lock and Unlock interfaces on the DirectSoundBuffer:
// Lock down the DirectSound buffer
if (DS_OK == lpDSB->Lock
(0, // Offset into buffer to start writing
WaveFile.cbSize, // Size of wave file to copy in
&pbData, // Points to first block of sound data
&dwLength, // Length of first block of data
&pbData2, // Points to second block of sound data
&dwLength2, // Length of second block of data
0L)) // Flags
{
// Copy first chunk
memcpy(pbData, WaveFile.pbData, dwLength);
// Copy second chunk
if (dwLength2)
memcpy(pbData2, WaveFile.pbData+dwLength , dwLength2);
// Free up the memory allocated in the WAVE_LoadFile function, since we
// have copied it to the buffer
free (lpWaveData);
// Unlock the buffer
if (DS_OK != lpDSB->Unlock(pbData, dwLength, pbData2, dwLength2))
OutputDebugStringA("Unlock failed");
}
else
{
OutputDebugStringA("Lock failed");
}
} // LoadWave