此代码在vs2008下编译,基于最新的ffmpeg版本(svn下载),搭建MSYS+MinGW编译环境编译,如何搭建,在google上能搜索到。 源码可在此 下载。
但除了aac和ogg格式播放出错,其余格式正常,不知为何,有ffmpeg开发经验的朋友请给予帮助,谢谢。代码贴于下方。
但除了aac和ogg格式播放出错,其余格式正常,不知为何,有ffmpeg开发经验的朋友请给予帮助,谢谢。代码贴于下方。
1
#include
<
stdio.h
>
2 #include < stdlib.h >
3 #include < windows.h >
4 #include < mmsystem.h >
5
6 #pragma comment(lib, " winmm.lib " )
7
8 #ifdef __cplusplus
9 extern " C " {
10#endif
11
12#include "./include/avcodec.h"
13#include "./include/avformat.h"
14#include "./include/avutil.h"
15#include "./include/mem.h"
16
17#ifdef __cplusplus
18}
19 #endif
20
21 #define BLOCK_SIZE 4608
22 #define BLOCK_COUNT 20
23
24 HWAVEOUT hWaveOut = NULL;
25
26 static void CALLBACK waveOutProc(HWAVEOUT, UINT, DWORD, DWORD, DWORD);
27 static WAVEHDR * allocateBlocks( int size, int count);
28 static void freeBlocks(WAVEHDR * blockArray);
29 static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size);
30
31 static CRITICAL_SECTION waveCriticalSection;
32 static WAVEHDR * waveBlocks;
33 static volatile unsigned int waveFreeBlockCount;
34 static int waveCurrentBlock;
35
36 typedef struct AudioState {
37 AVFormatContext* pFmtCtx;
38 AVCodecContext* pCodecCtx;
39 AVCodec* pCodec;
40 uint8_t audio_buf1[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
41 uint8_t* audio_buf;
42 unsigned int audio_buf_size;
43 int audio_buf_index;
44 AVPacket audio_pkt_temp;
45 AVPacket audio_pkt;
46 uint8_t* audio_pkt_data;
47 int audio_pkt_size;
48 int stream_index;
49} AudioState;
50
51 int audio_decode_frame(AudioState * pState) {
52
53 AVPacket* pkt_temp = &pState->audio_pkt_temp;
54 AVPacket* pkt = &pState->audio_pkt;
55 AVCodecContext* dec= pState->pCodecCtx;
56 int len = 0, data_size = sizeof(pState->audio_buf1);
57 int err = 0;
58
59 for( ; ; ) {
60 while (pkt_temp->size > 0) {
61 data_size = sizeof(pState->audio_buf1);
62 len = avcodec_decode_audio3(dec, (int16_t*)pState->audio_buf1, &data_size, pkt_temp);
63 if (len < 0) {
64 pkt_temp->size = 0;
65 break;
66 }
67
68 pkt_temp->data += len;
69 pkt_temp->size -= len;
70
71 if (data_size <= 0)
72 continue;
73
74 pState->audio_buf = pState->audio_buf1;
75 return data_size;
76 }
77
78 if (pkt->data)
79 av_free_packet(pkt);
80
81 if((err = av_read_frame(pState->pFmtCtx, pkt)) < 0)
82 return -1;
83
84 pkt_temp->data = pkt->data;
85 pkt_temp->size = pkt->size;
86 }
87
88 return -1;
89}
90
91 int main( int argc, char * argv[]) {
92 int err = 0;
93 AudioState audio_state = {0};
94 unsigned int i = 0;
95 unsigned int ready = 0;
96
97 OPENFILENAME ofn = {0};
98 char filename[MAX_PATH];
99 WAVEFORMATEX wfx = {0};
100 uint8_t buffer[BLOCK_SIZE];
101 uint8_t* pbuffer = buffer;
102 AVInputFormat* iformat = NULL;
103
104 int audio_size = 0, data_size = 0;
105 int len = 0, len1 = 0, eof = 0, size = 0;
106
107 memset(&ofn, 0, sizeof(OPENFILENAME));
108 ofn.lStructSize = sizeof(ofn);
109 ofn.hwndOwner = GetDesktopWindow();
110 ofn.lpstrFile = filename;
111 ofn.lpstrFile[0] = '\0';
112 ofn.nMaxFile = sizeof(filename) / sizeof(filename[0]);
113 ofn.lpstrFilter = _TEXT("All support files\0*.aac;*.ape;*.flac;*.mp3;*.mp4;*.mpc;*.ogg;*.tta;*.wma;*.wav\0");
114 ofn.nFilterIndex = 1;
115 ofn.lpstrFileTitle = NULL;
116 ofn.nMaxFileTitle = 0;
117 ofn.lpstrInitialDir = NULL;
118 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
119
120 if (GetOpenFileName(&ofn) == FALSE)
121 return 0;
122
123 av_register_all();
124
125 err = av_open_input_file(&audio_state.pFmtCtx, filename, NULL, 0, NULL);
126 if(err < 0) {
127 printf("can not open file %s.\n", filename);
128 return -1;
129 }
130
131 err = av_find_stream_info(audio_state.pFmtCtx);
132 if(err < 0) {
133 printf("can not find stream info of file %s.\n", filename);
134 return -1;
135 }
136
137 for(i = 0; i < audio_state.pFmtCtx->nb_streams; i++) {
138 if(audio_state.pFmtCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
139 audio_state.pCodecCtx = audio_state.pFmtCtx->streams[i]->codec;
140 audio_state.stream_index = i;
141 ready = 1;
142 break;
143 }
144 }
145
146 if(!ready)
147 return -1;
148
149 audio_state.pCodec = avcodec_find_decoder(audio_state.pCodecCtx->codec_id);
150 if(!audio_state.pCodec || avcodec_open(audio_state.pCodecCtx, audio_state.pCodec) < 0)
151 return -1;
152
153 wfx.nSamplesPerSec = audio_state.pCodecCtx->sample_rate;
154 switch(audio_state.pCodecCtx->sample_fmt)
155 {
156 case SAMPLE_FMT_U8:
157 wfx.wBitsPerSample = 8;
158 break;
159 case SAMPLE_FMT_S16:
160 wfx.wBitsPerSample = 16;
161 break;
162 case SAMPLE_FMT_S32:
163 wfx.wBitsPerSample = 32;
164 break;
165 case SAMPLE_FMT_FLT:
166 wfx.wBitsPerSample = sizeof(double) * 8;
167 break;
168 default:
169 wfx.wBitsPerSample = 0;
170 break;
171 }
172
173 wfx.nChannels = FFMIN(2, audio_state.pCodecCtx->channels);
174 wfx.cbSize = 0;
175 wfx.wFormatTag = WAVE_FORMAT_PCM;
176 wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
177 wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
178
179 waveBlocks = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
180 waveFreeBlockCount = BLOCK_COUNT;
181 waveCurrentBlock = 0;
182
183 InitializeCriticalSection(&waveCriticalSection);
184
185 // open wave out device
186 if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (DWORD_PTR)waveOutProc,
187 (DWORD_PTR)&waveFreeBlockCount, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
188 fprintf(stderr, "%s: unable to open wave mapper device\n", argv[0]);
189 ExitProcess(1);
190 }
191
192 // play loop
193 for( ; ; ) {
194
195 len = BLOCK_SIZE;
196 size = 0;
197 pbuffer = buffer;
198
199 if(eof)
200 break;
201
202 while(len > 0) {
203 if(audio_state.audio_buf_index >= (int)audio_state.audio_buf_size) {
204 audio_size = audio_decode_frame(&audio_state);
205 if(audio_size < 0) {
206 if(size > 0)
207 break;
208
209 eof = 1;
210 break;
211 }
212
213 audio_state.audio_buf_size = audio_size;
214 audio_state.audio_buf_index = 0;
215 }
216
217 len1 = audio_state.audio_buf_size - audio_state.audio_buf_index;
218 if(len1 > len)
219 len1 = len;
220
221 memcpy(pbuffer, (uint8_t *)audio_state.audio_buf + audio_state.audio_buf_index, len1);
222
223 len -= len1;
224 pbuffer += len1;
225 size += len1;
226 audio_state.audio_buf_index += len1;
227 }
228
229 writeAudio(hWaveOut, (char*)buffer, size);
230 }
231
232 // wait for complete
233 for( ; ; ) {
234 if(waveFreeBlockCount >= BLOCK_COUNT)
235 break;
236
237 Sleep(10);
238 }
239
240 for(i = 0; i < waveFreeBlockCount; i++)
241 if(waveBlocks[i].dwFlags & WHDR_PREPARED)
242 waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));
243
244 DeleteCriticalSection(&waveCriticalSection);
245 freeBlocks(waveBlocks);
246 waveOutClose(hWaveOut);
247
248 avcodec_close(audio_state.pCodecCtx);
249
250 system("pause");
251 return 0;
252}
253
254 static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size)
255 {
256 WAVEHDR* current;
257 int remain;
258
259 current = &waveBlocks[waveCurrentBlock];
260
261 while(size > 0) {
262 /**//*
263 * first make sure the header we're going to use is unprepared
264 */
265 if(current->dwFlags & WHDR_PREPARED)
266 waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
267
268 if(size < (int)(BLOCK_SIZE - current->dwUser)) {
269 memcpy(current->lpData + current->dwUser, data, size);
270 current->dwUser += size;
271 break;
272 }
273
274 remain = BLOCK_SIZE - current->dwUser;
275 memcpy(current->lpData + current->dwUser, data, remain);
276 size -= remain;
277 data += remain;
278 current->dwBufferLength = BLOCK_SIZE;
279
280 waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
281 waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
282
283 EnterCriticalSection(&waveCriticalSection);
284 waveFreeBlockCount--;
285 LeaveCriticalSection(&waveCriticalSection);
286
287 /**//*
288 * wait for a block to become free
289 */
290 while(!waveFreeBlockCount)
291 Sleep(10);
292
293 /**//*
294 * point to the next block
295 */
296 waveCurrentBlock++;
297 waveCurrentBlock %= BLOCK_COUNT;
298
299 current = &waveBlocks[waveCurrentBlock];
300 current->dwUser = 0;
301 }
302}
303
304 static WAVEHDR * allocateBlocks( int size, int count)
305 {
306 char* buffer;
307 int i;
308 WAVEHDR* blocks;
309 DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
310
311 /**//*
312 * allocate memory for the entire set in one go
313 */
314 if((buffer = (char*)HeapAlloc(
315 GetProcessHeap(),
316 HEAP_ZERO_MEMORY,
317 totalBufferSize
318 )) == NULL) {
319 fprintf(stderr, "Memory allocation error\n");
320 ExitProcess(1);
321 }
322
323 /**//*
324 * and set up the pointers to each bit
325 */
326 blocks = (WAVEHDR*)buffer;
327 buffer += sizeof(WAVEHDR) * count;
328 for(i = 0; i < count; i++) {
329 blocks[i].dwBufferLength = size;
330 blocks[i].lpData = buffer;
331 buffer += size;
332 }
333
334 return blocks;
335}
336
337 static void freeBlocks(WAVEHDR * blockArray)
338 {
339 /**//*
340 * and this is why allocateBlocks works the way it does
341 */
342 HeapFree(GetProcessHeap(), 0, blockArray);
343}
344
345 static void CALLBACK waveOutProc(
346 HWAVEOUT hWaveOut,
347 UINT uMsg,
348 DWORD dwInstance,
349 DWORD dwParam1,
350 DWORD dwParam2
351 )
352 {
353 int* freeBlockCounter = (int*)dwInstance;
354 /**//*
355 * ignore calls that occur due to opening and closing the
356 * device.
357 */
358 if(uMsg != WOM_DONE)
359 return;
360
361 EnterCriticalSection(&waveCriticalSection);
362 (*freeBlockCounter)++;
363 LeaveCriticalSection(&waveCriticalSection);
364}
2 #include < stdlib.h >
3 #include < windows.h >
4 #include < mmsystem.h >
5
6 #pragma comment(lib, " winmm.lib " )
7
8 #ifdef __cplusplus
9 extern " C " {
10#endif
11
12#include "./include/avcodec.h"
13#include "./include/avformat.h"
14#include "./include/avutil.h"
15#include "./include/mem.h"
16
17#ifdef __cplusplus
18}
19 #endif
20
21 #define BLOCK_SIZE 4608
22 #define BLOCK_COUNT 20
23
24 HWAVEOUT hWaveOut = NULL;
25
26 static void CALLBACK waveOutProc(HWAVEOUT, UINT, DWORD, DWORD, DWORD);
27 static WAVEHDR * allocateBlocks( int size, int count);
28 static void freeBlocks(WAVEHDR * blockArray);
29 static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size);
30
31 static CRITICAL_SECTION waveCriticalSection;
32 static WAVEHDR * waveBlocks;
33 static volatile unsigned int waveFreeBlockCount;
34 static int waveCurrentBlock;
35
36 typedef struct AudioState {
37 AVFormatContext* pFmtCtx;
38 AVCodecContext* pCodecCtx;
39 AVCodec* pCodec;
40 uint8_t audio_buf1[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2];
41 uint8_t* audio_buf;
42 unsigned int audio_buf_size;
43 int audio_buf_index;
44 AVPacket audio_pkt_temp;
45 AVPacket audio_pkt;
46 uint8_t* audio_pkt_data;
47 int audio_pkt_size;
48 int stream_index;
49} AudioState;
50
51 int audio_decode_frame(AudioState * pState) {
52
53 AVPacket* pkt_temp = &pState->audio_pkt_temp;
54 AVPacket* pkt = &pState->audio_pkt;
55 AVCodecContext* dec= pState->pCodecCtx;
56 int len = 0, data_size = sizeof(pState->audio_buf1);
57 int err = 0;
58
59 for( ; ; ) {
60 while (pkt_temp->size > 0) {
61 data_size = sizeof(pState->audio_buf1);
62 len = avcodec_decode_audio3(dec, (int16_t*)pState->audio_buf1, &data_size, pkt_temp);
63 if (len < 0) {
64 pkt_temp->size = 0;
65 break;
66 }
67
68 pkt_temp->data += len;
69 pkt_temp->size -= len;
70
71 if (data_size <= 0)
72 continue;
73
74 pState->audio_buf = pState->audio_buf1;
75 return data_size;
76 }
77
78 if (pkt->data)
79 av_free_packet(pkt);
80
81 if((err = av_read_frame(pState->pFmtCtx, pkt)) < 0)
82 return -1;
83
84 pkt_temp->data = pkt->data;
85 pkt_temp->size = pkt->size;
86 }
87
88 return -1;
89}
90
91 int main( int argc, char * argv[]) {
92 int err = 0;
93 AudioState audio_state = {0};
94 unsigned int i = 0;
95 unsigned int ready = 0;
96
97 OPENFILENAME ofn = {0};
98 char filename[MAX_PATH];
99 WAVEFORMATEX wfx = {0};
100 uint8_t buffer[BLOCK_SIZE];
101 uint8_t* pbuffer = buffer;
102 AVInputFormat* iformat = NULL;
103
104 int audio_size = 0, data_size = 0;
105 int len = 0, len1 = 0, eof = 0, size = 0;
106
107 memset(&ofn, 0, sizeof(OPENFILENAME));
108 ofn.lStructSize = sizeof(ofn);
109 ofn.hwndOwner = GetDesktopWindow();
110 ofn.lpstrFile = filename;
111 ofn.lpstrFile[0] = '\0';
112 ofn.nMaxFile = sizeof(filename) / sizeof(filename[0]);
113 ofn.lpstrFilter = _TEXT("All support files\0*.aac;*.ape;*.flac;*.mp3;*.mp4;*.mpc;*.ogg;*.tta;*.wma;*.wav\0");
114 ofn.nFilterIndex = 1;
115 ofn.lpstrFileTitle = NULL;
116 ofn.nMaxFileTitle = 0;
117 ofn.lpstrInitialDir = NULL;
118 ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
119
120 if (GetOpenFileName(&ofn) == FALSE)
121 return 0;
122
123 av_register_all();
124
125 err = av_open_input_file(&audio_state.pFmtCtx, filename, NULL, 0, NULL);
126 if(err < 0) {
127 printf("can not open file %s.\n", filename);
128 return -1;
129 }
130
131 err = av_find_stream_info(audio_state.pFmtCtx);
132 if(err < 0) {
133 printf("can not find stream info of file %s.\n", filename);
134 return -1;
135 }
136
137 for(i = 0; i < audio_state.pFmtCtx->nb_streams; i++) {
138 if(audio_state.pFmtCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
139 audio_state.pCodecCtx = audio_state.pFmtCtx->streams[i]->codec;
140 audio_state.stream_index = i;
141 ready = 1;
142 break;
143 }
144 }
145
146 if(!ready)
147 return -1;
148
149 audio_state.pCodec = avcodec_find_decoder(audio_state.pCodecCtx->codec_id);
150 if(!audio_state.pCodec || avcodec_open(audio_state.pCodecCtx, audio_state.pCodec) < 0)
151 return -1;
152
153 wfx.nSamplesPerSec = audio_state.pCodecCtx->sample_rate;
154 switch(audio_state.pCodecCtx->sample_fmt)
155 {
156 case SAMPLE_FMT_U8:
157 wfx.wBitsPerSample = 8;
158 break;
159 case SAMPLE_FMT_S16:
160 wfx.wBitsPerSample = 16;
161 break;
162 case SAMPLE_FMT_S32:
163 wfx.wBitsPerSample = 32;
164 break;
165 case SAMPLE_FMT_FLT:
166 wfx.wBitsPerSample = sizeof(double) * 8;
167 break;
168 default:
169 wfx.wBitsPerSample = 0;
170 break;
171 }
172
173 wfx.nChannels = FFMIN(2, audio_state.pCodecCtx->channels);
174 wfx.cbSize = 0;
175 wfx.wFormatTag = WAVE_FORMAT_PCM;
176 wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) >> 3;
177 wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
178
179 waveBlocks = allocateBlocks(BLOCK_SIZE, BLOCK_COUNT);
180 waveFreeBlockCount = BLOCK_COUNT;
181 waveCurrentBlock = 0;
182
183 InitializeCriticalSection(&waveCriticalSection);
184
185 // open wave out device
186 if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfx, (DWORD_PTR)waveOutProc,
187 (DWORD_PTR)&waveFreeBlockCount, CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
188 fprintf(stderr, "%s: unable to open wave mapper device\n", argv[0]);
189 ExitProcess(1);
190 }
191
192 // play loop
193 for( ; ; ) {
194
195 len = BLOCK_SIZE;
196 size = 0;
197 pbuffer = buffer;
198
199 if(eof)
200 break;
201
202 while(len > 0) {
203 if(audio_state.audio_buf_index >= (int)audio_state.audio_buf_size) {
204 audio_size = audio_decode_frame(&audio_state);
205 if(audio_size < 0) {
206 if(size > 0)
207 break;
208
209 eof = 1;
210 break;
211 }
212
213 audio_state.audio_buf_size = audio_size;
214 audio_state.audio_buf_index = 0;
215 }
216
217 len1 = audio_state.audio_buf_size - audio_state.audio_buf_index;
218 if(len1 > len)
219 len1 = len;
220
221 memcpy(pbuffer, (uint8_t *)audio_state.audio_buf + audio_state.audio_buf_index, len1);
222
223 len -= len1;
224 pbuffer += len1;
225 size += len1;
226 audio_state.audio_buf_index += len1;
227 }
228
229 writeAudio(hWaveOut, (char*)buffer, size);
230 }
231
232 // wait for complete
233 for( ; ; ) {
234 if(waveFreeBlockCount >= BLOCK_COUNT)
235 break;
236
237 Sleep(10);
238 }
239
240 for(i = 0; i < waveFreeBlockCount; i++)
241 if(waveBlocks[i].dwFlags & WHDR_PREPARED)
242 waveOutUnprepareHeader(hWaveOut, &waveBlocks[i], sizeof(WAVEHDR));
243
244 DeleteCriticalSection(&waveCriticalSection);
245 freeBlocks(waveBlocks);
246 waveOutClose(hWaveOut);
247
248 avcodec_close(audio_state.pCodecCtx);
249
250 system("pause");
251 return 0;
252}
253
254 static void writeAudio(HWAVEOUT hWaveOut, LPSTR data, int size)
255 {
256 WAVEHDR* current;
257 int remain;
258
259 current = &waveBlocks[waveCurrentBlock];
260
261 while(size > 0) {
262 /**//*
263 * first make sure the header we're going to use is unprepared
264 */
265 if(current->dwFlags & WHDR_PREPARED)
266 waveOutUnprepareHeader(hWaveOut, current, sizeof(WAVEHDR));
267
268 if(size < (int)(BLOCK_SIZE - current->dwUser)) {
269 memcpy(current->lpData + current->dwUser, data, size);
270 current->dwUser += size;
271 break;
272 }
273
274 remain = BLOCK_SIZE - current->dwUser;
275 memcpy(current->lpData + current->dwUser, data, remain);
276 size -= remain;
277 data += remain;
278 current->dwBufferLength = BLOCK_SIZE;
279
280 waveOutPrepareHeader(hWaveOut, current, sizeof(WAVEHDR));
281 waveOutWrite(hWaveOut, current, sizeof(WAVEHDR));
282
283 EnterCriticalSection(&waveCriticalSection);
284 waveFreeBlockCount--;
285 LeaveCriticalSection(&waveCriticalSection);
286
287 /**//*
288 * wait for a block to become free
289 */
290 while(!waveFreeBlockCount)
291 Sleep(10);
292
293 /**//*
294 * point to the next block
295 */
296 waveCurrentBlock++;
297 waveCurrentBlock %= BLOCK_COUNT;
298
299 current = &waveBlocks[waveCurrentBlock];
300 current->dwUser = 0;
301 }
302}
303
304 static WAVEHDR * allocateBlocks( int size, int count)
305 {
306 char* buffer;
307 int i;
308 WAVEHDR* blocks;
309 DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
310
311 /**//*
312 * allocate memory for the entire set in one go
313 */
314 if((buffer = (char*)HeapAlloc(
315 GetProcessHeap(),
316 HEAP_ZERO_MEMORY,
317 totalBufferSize
318 )) == NULL) {
319 fprintf(stderr, "Memory allocation error\n");
320 ExitProcess(1);
321 }
322
323 /**//*
324 * and set up the pointers to each bit
325 */
326 blocks = (WAVEHDR*)buffer;
327 buffer += sizeof(WAVEHDR) * count;
328 for(i = 0; i < count; i++) {
329 blocks[i].dwBufferLength = size;
330 blocks[i].lpData = buffer;
331 buffer += size;
332 }
333
334 return blocks;
335}
336
337 static void freeBlocks(WAVEHDR * blockArray)
338 {
339 /**//*
340 * and this is why allocateBlocks works the way it does
341 */
342 HeapFree(GetProcessHeap(), 0, blockArray);
343}
344
345 static void CALLBACK waveOutProc(
346 HWAVEOUT hWaveOut,
347 UINT uMsg,
348 DWORD dwInstance,
349 DWORD dwParam1,
350 DWORD dwParam2
351 )
352 {
353 int* freeBlockCounter = (int*)dwInstance;
354 /**//*
355 * ignore calls that occur due to opening and closing the
356 * device.
357 */
358 if(uMsg != WOM_DONE)
359 return;
360
361 EnterCriticalSection(&waveCriticalSection);
362 (*freeBlockCounter)++;
363 LeaveCriticalSection(&waveCriticalSection);
364}