|
|
1.1 ! root 1: /* reverse.c - WinMain() and WndProc() for REVERSE, along with ! 2: * initialization and support code. ! 3: * ! 4: * REVERSE is a Windows with Multimedia sample application that ! 5: * illustrates how to use the low-level waveform playback services. ! 6: * It also shows how to use the multimedia file I/O services to read ! 7: * data from a WAVE file. ! 8: * ! 9: * REVERSE plays a WAVE waveform audio file backwards. ! 10: * ! 11: * (C) Copyright Microsoft Corp. 1991, 1992. All rights reserved. ! 12: * ! 13: * You have a royalty-free right to use, modify, reproduce and ! 14: * distribute the Sample Files (and/or any modified version) in ! 15: * any way you find useful, provided that you agree that ! 16: * Microsoft has no warranty obligations or liability for any ! 17: * Sample Application Files which are modified. ! 18: * ! 19: */ ! 20: ! 21: #include <windows.h> ! 22: #include <mmsystem.h> ! 23: #include "reverse.h" ! 24: ! 25: #define MAX_FILENAME_SIZE 128 ! 26: ! 27: /* Global variables. ! 28: */ ! 29: char szAppName[] = "Reverse"; // application name ! 30: HANDLE hInstApp = NULL; // instance handle ! 31: HWND hwndApp = NULL; // main window handle ! 32: HWND hwndName = NULL; // filename window handle ! 33: HWND hwndPlay = NULL; // "Play" button window handle ! 34: HWND hwndQuit = NULL; // "Exit" button window handle ! 35: HWAVEOUT hWaveOut = NULL; ! 36: LPWAVEHDR lpWaveHdr = NULL; ! 37: VOID cleanup(LPWAVEINST lpWaveInst); ! 38: ! 39: ! 40: /* WinMain - Entry point for Reverse. ! 41: */ ! 42: int PASCAL WinMain(HANDLE hInst, HANDLE hPrev, LPSTR szCmdLine, int cmdShow) ! 43: { ! 44: MSG msg; ! 45: WNDCLASS wc; ! 46: ! 47: hInstApp = hInst; ! 48: ! 49: /* Define and register a window class for the main window. ! 50: */ ! 51: if (!hPrev) ! 52: { ! 53: wc.hCursor = LoadCursor(NULL, IDC_ARROW); ! 54: wc.hIcon = LoadIcon(hInst, szAppName); ! 55: wc.lpszMenuName = szAppName; ! 56: wc.lpszClassName = szAppName; ! 57: wc.hbrBackground = GetStockObject(LTGRAY_BRUSH); ! 58: wc.hInstance = hInst; ! 59: wc.style = 0; ! 60: wc.lpfnWndProc = WndProc; ! 61: wc.cbWndExtra = 0; ! 62: wc.cbClsExtra = 0; ! 63: ! 64: if (!RegisterClass(&wc)) ! 65: return FALSE; ! 66: } ! 67: ! 68: /* Create and show the main window. ! 69: */ ! 70: hwndApp = CreateWindow (szAppName, // class name ! 71: szAppName, // caption ! 72: WS_OVERLAPPEDWINDOW, // style bits ! 73: CW_USEDEFAULT, // x position ! 74: CW_USEDEFAULT, // y position ! 75: WMAIN_DX, // x size ! 76: WMAIN_DY, // y size ! 77: (HWND)NULL, // parent window ! 78: (HMENU)NULL, // use class menu ! 79: (HANDLE)hInst, // instance handle ! 80: (LPSTR)NULL // no params to pass on ! 81: ); ! 82: /* Create child windows for the "Play" and "Exit" buttons ! 83: * and for an edit field to enter filenames. ! 84: */ ! 85: hwndPlay = CreateWindow( "BUTTON", "Play", ! 86: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, ! 87: PLAY_X, PLAY_Y, ! 88: PLAY_DX, PLAY_DY, ! 89: hwndApp, (HMENU)IDB_PLAY, hInstApp, NULL ); ! 90: if( !hwndPlay ) ! 91: return( FALSE ); ! 92: ! 93: hwndQuit = CreateWindow( "BUTTON", "Exit", ! 94: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, ! 95: QUIT_X, QUIT_Y, ! 96: QUIT_DX, QUIT_DY, ! 97: hwndApp, (HMENU)IDB_QUIT, hInstApp, NULL ); ! 98: if( !hwndQuit ) ! 99: return( FALSE ); ! 100: ! 101: hwndName = CreateWindow("EDIT","", ! 102: WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL, ! 103: NAME_X, NAME_Y, ! 104: NAME_DX, NAME_DY, ! 105: hwndApp, (HMENU)IDE_NAME, hInstApp, NULL); ! 106: if( !hwndName ) ! 107: return( FALSE ); ! 108: SendMessage(hwndName, EM_LIMITTEXT, MAX_FILENAME_SIZE - 1, 0); ! 109: ! 110: ShowWindow(hwndApp,cmdShow); ! 111: ! 112: /* Add about dialog to system menu. ! 113: */ ! 114: AppendMenu(GetSystemMenu(hwndApp, NULL), ! 115: MF_STRING | MF_ENABLED, IDM_ABOUT, "About Reverse..."); ! 116: ! 117: ! 118: /* The main message processing loop. Nothing special here. ! 119: */ ! 120: while (GetMessage(&msg,NULL,0,0)) ! 121: { ! 122: TranslateMessage(&msg); ! 123: DispatchMessage(&msg); ! 124: } ! 125: ! 126: return msg.wParam; ! 127: } ! 128: ! 129: ! 130: /* WndProc - Main window procedure function. ! 131: */ ! 132: LONG FAR PASCAL WndProc(HWND hWnd, unsigned msg, UINT wParam, LONG lParam) ! 133: { ! 134: FARPROC fpfn; ! 135: LPWAVEINST lpWaveInst; ! 136: ! 137: switch (msg) ! 138: { ! 139: case WM_DESTROY: ! 140: if (hWaveOut) ! 141: { ! 142: waveOutReset(hWaveOut); ! 143: waveOutUnprepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR) ); ! 144: lpWaveInst = (LPWAVEINST) lpWaveHdr->dwUser; ! 145: cleanup(lpWaveInst); ! 146: waveOutClose(hWaveOut); ! 147: } ! 148: PostQuitMessage(0); ! 149: break; ! 150: ! 151: case WM_SYSCOMMAND: ! 152: switch (LOWORD(wParam)) ! 153: { ! 154: case IDM_ABOUT: ! 155: /* Show ABOUTBOX dialog box. ! 156: */ ! 157: fpfn = MakeProcInstance((FARPROC)AppAbout, hInstApp); // no op in 32 bit ! 158: DialogBox(hInstApp, "ABOUTBOX", hWnd, (DLGPROC)fpfn); ! 159: FreeProcInstance(fpfn); ! 160: break; ! 161: } ! 162: break; ! 163: ! 164: /* Process messages sent by the child window controls. ! 165: */ ! 166: case WM_SETFOCUS: ! 167: SetFocus(hwndName); ! 168: return 0; ! 169: ! 170: case WM_COMMAND: ! 171: switch (LOWORD(wParam)) ! 172: { ! 173: case IDE_NAME: // filename edit control ! 174: return( 0L ); ! 175: ! 176: case IDB_PLAY: // "Play" button ! 177: if (HIWORD(wParam) == BN_CLICKED) ! 178: ReversePlay(); ! 179: break; ! 180: ! 181: case IDB_QUIT: // "Exit" button ! 182: if (HIWORD(wParam) == BN_CLICKED) ! 183: PostQuitMessage(0); ! 184: break; ! 185: } ! 186: return( 0L ); ! 187: ! 188: case MM_WOM_DONE: ! 189: /* This message indicates a waveform data block has ! 190: * been played and can be freed. Clean up the preparation ! 191: * done previously on the header. ! 192: */ ! 193: waveOutUnprepareHeader( (HWAVEOUT) wParam, ! 194: (LPWAVEHDR) lParam, sizeof(WAVEHDR) ); ! 195: ! 196: /* Get a pointer to the instance data, then unlock and free ! 197: * all memory associated with the data block, including the ! 198: * memory for the instance data itself. ! 199: */ ! 200: lpWaveInst = (LPWAVEINST) ((LPWAVEHDR)lParam)->dwUser; ! 201: cleanup(lpWaveInst); ! 202: /* Close the waveform output device. ! 203: */ ! 204: waveOutClose( (HWAVEOUT) wParam ); ! 205: ! 206: /* Reenable both button controls. ! 207: */ ! 208: EnableWindow( hwndPlay, TRUE ); ! 209: EnableWindow( hwndQuit, TRUE ); ! 210: SetFocus(hwndName); ! 211: ! 212: break; ! 213: } ! 214: ! 215: return DefWindowProc(hWnd,msg,wParam,lParam); ! 216: } ! 217: ! 218: ! 219: /* AppAbout -- Dialog procedure for ABOUTBOX dialog box. ! 220: */ ! 221: BOOL FAR PASCAL AppAbout(HWND hDlg, unsigned msg, unsigned wParam, LONG lParam) ! 222: { ! 223: switch (msg) ! 224: { ! 225: case WM_COMMAND: ! 226: if (LOWORD(wParam) == IDOK) ! 227: EndDialog(hDlg,TRUE); ! 228: break; ! 229: ! 230: case WM_INITDIALOG: ! 231: return TRUE; ! 232: } ! 233: return FALSE; ! 234: } ! 235: ! 236: /* ReversePlay - Gets a filename from the edit control, then uses ! 237: * the multimedia file I/O services to read data from the requested ! 238: * WAVE file. If the file is a proper WAVE file, ReversePlay() calls ! 239: * the Interchange() function to reverse the order of the waveform ! 240: * samples in the file. It then plays the reversed waveform data. ! 241: * ! 242: * Note that ReversePlay() only handles a single waveform data block. ! 243: * If the requested WAVE file will not fit in a single data block, it ! 244: * will not be played. The size of a single data block depends on the ! 245: * amount of available system memory. ! 246: * ! 247: * Params: void ! 248: * ! 249: * Return: void ! 250: */ ! 251: void ReversePlay() ! 252: { ! 253: HANDLE hWaveHdr; ! 254: LPWAVEINST lpWaveInst; ! 255: HMMIO hmmio; ! 256: MMCKINFO mmckinfoParent; ! 257: MMCKINFO mmckinfoSubchunk; ! 258: DWORD dwFmtSize; ! 259: char szFileName[ MAX_FILENAME_SIZE ]; ! 260: HANDLE hFormat; ! 261: WAVEFORMAT *pFormat; ! 262: DWORD dwDataSize; ! 263: HPSTR hpch1, hpch2; ! 264: WORD wBlockSize; ! 265: HANDLE hWaveInst; ! 266: HANDLE hData = NULL; ! 267: HPSTR lpData = NULL; ! 268: ! 269: /* Get the filename from the edit control. ! 270: */ ! 271: if (!GetWindowText( hwndName, (LPSTR)szFileName, MAX_FILENAME_SIZE)) ! 272: { ! 273: MessageBox(hwndApp, "Failed to Get Filename", ! 274: NULL, MB_OK | MB_ICONEXCLAMATION); ! 275: return; ! 276: } ! 277: ! 278: /* Open the given file for reading using buffered I/O. ! 279: */ ! 280: if(!(hmmio = mmioOpen(szFileName, NULL, MMIO_READ | MMIO_ALLOCBUF))) ! 281: { ! 282: MessageBox(hwndApp, "Failed to open file.", ! 283: NULL, MB_OK | MB_ICONEXCLAMATION); ! 284: return; ! 285: } ! 286: ! 287: /* Locate a 'RIFF' chunk with a 'WAVE' form type ! 288: * to make sure it's a WAVE file. ! 289: */ ! 290: mmckinfoParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); ! 291: if (mmioDescend(hmmio, (LPMMCKINFO) &mmckinfoParent, NULL, MMIO_FINDRIFF)) ! 292: { ! 293: MessageBox(hwndApp, "This is not a WAVE file.", ! 294: NULL, MB_OK | MB_ICONEXCLAMATION); ! 295: mmioClose(hmmio, 0); ! 296: return; ! 297: } ! 298: ! 299: /* Now, find the format chunk (form type 'fmt '). It should be ! 300: * a subchunk of the 'RIFF' parent chunk. ! 301: */ ! 302: mmckinfoSubchunk.ckid = mmioFOURCC('f', 'm', 't', ' '); ! 303: if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, ! 304: MMIO_FINDCHUNK)) ! 305: { ! 306: MessageBox(hwndApp, "WAVE file is corrupted.", ! 307: NULL, MB_OK | MB_ICONEXCLAMATION); ! 308: mmioClose(hmmio, 0); ! 309: return; ! 310: } ! 311: ! 312: /* Get the size of the format chunk, allocate and lock memory for it. ! 313: */ ! 314: dwFmtSize = mmckinfoSubchunk.cksize; ! 315: hFormat = LocalAlloc(LMEM_MOVEABLE, LOWORD(dwFmtSize)); ! 316: if (!hFormat) ! 317: { ! 318: MessageBox(hwndApp, "Out of memory.", ! 319: NULL, MB_OK | MB_ICONEXCLAMATION); ! 320: mmioClose(hmmio, 0); ! 321: return; ! 322: } ! 323: pFormat = (WAVEFORMAT *) LocalLock(hFormat); ! 324: if (!pFormat) ! 325: { ! 326: MessageBox(hwndApp, "Failed to lock memory for format chunk.", ! 327: NULL, MB_OK | MB_ICONEXCLAMATION); ! 328: LocalFree( hFormat ); ! 329: mmioClose(hmmio, 0); ! 330: return; ! 331: } ! 332: ! 333: /* Read the format chunk. ! 334: */ ! 335: if (mmioRead(hmmio, (HPSTR) pFormat, dwFmtSize) != (LONG) dwFmtSize) ! 336: { ! 337: MessageBox(hwndApp, "Failed to read format chunk.", ! 338: NULL, MB_OK | MB_ICONEXCLAMATION); ! 339: LocalUnlock( hFormat ); ! 340: LocalFree( hFormat ); ! 341: mmioClose(hmmio, 0); ! 342: return; ! 343: } ! 344: ! 345: /* Make sure it's a PCM file. ! 346: */ ! 347: if (pFormat->wFormatTag != WAVE_FORMAT_PCM) ! 348: { ! 349: LocalUnlock( hFormat ); ! 350: LocalFree( hFormat ); ! 351: mmioClose(hmmio, 0); ! 352: MessageBox(hwndApp, "The file is not a PCM file.", ! 353: NULL, MB_OK | MB_ICONEXCLAMATION); ! 354: return; ! 355: } ! 356: ! 357: /* Make sure a waveform output device supports this format. ! 358: */ ! 359: if (waveOutOpen(&hWaveOut, WAVE_MAPPER, (LPWAVEFORMAT)pFormat, NULL, 0L, ! 360: WAVE_FORMAT_QUERY)) ! 361: { ! 362: LocalUnlock( hFormat ); ! 363: LocalFree( hFormat ); ! 364: mmioClose(hmmio, 0); ! 365: MessageBox(hwndApp, "The waveform device can't play this format.", ! 366: NULL, MB_OK | MB_ICONEXCLAMATION); ! 367: return; ! 368: } ! 369: ! 370: /* Ascend out of the format subchunk. ! 371: */ ! 372: mmioAscend(hmmio, &mmckinfoSubchunk, 0); ! 373: ! 374: /* Find the data subchunk. ! 375: */ ! 376: mmckinfoSubchunk.ckid = mmioFOURCC('d', 'a', 't', 'a'); ! 377: if (mmioDescend(hmmio, &mmckinfoSubchunk, &mmckinfoParent, ! 378: MMIO_FINDCHUNK)) ! 379: { ! 380: MessageBox(hwndApp, "WAVE file has no data chunk.", ! 381: NULL, MB_OK | MB_ICONEXCLAMATION); ! 382: LocalUnlock( hFormat ); ! 383: LocalFree( hFormat ); ! 384: mmioClose(hmmio, 0); ! 385: return; ! 386: } ! 387: ! 388: /* Get the size of the data subchunk. ! 389: */ ! 390: dwDataSize = mmckinfoSubchunk.cksize; ! 391: if (dwDataSize == 0L) ! 392: { ! 393: MessageBox(hwndApp, "The data chunk has no data.", ! 394: NULL, MB_OK | MB_ICONEXCLAMATION); ! 395: LocalUnlock( hFormat ); ! 396: LocalFree( hFormat ); ! 397: mmioClose(hmmio, 0); ! 398: return; ! 399: } ! 400: ! 401: /* Open a waveform output device. ! 402: */ ! 403: if (waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, ! 404: (LPWAVEFORMAT)pFormat, (UINT)hwndApp, 0L, CALLBACK_WINDOW)) ! 405: { ! 406: MessageBox(hwndApp, "Failed to open waveform output device.", ! 407: NULL, MB_OK | MB_ICONEXCLAMATION); ! 408: LocalUnlock( hFormat ); ! 409: LocalFree( hFormat ); ! 410: mmioClose(hmmio, 0); ! 411: return; ! 412: } ! 413: ! 414: /* Save block alignment info for later use. ! 415: */ ! 416: wBlockSize = pFormat->nBlockAlign; ! 417: ! 418: /* We're done with the format header, free it. ! 419: */ ! 420: LocalUnlock( hFormat ); ! 421: LocalFree( hFormat ); ! 422: ! 423: /* Allocate and lock memory for the waveform data. ! 424: */ ! 425: hData = GlobalAlloc(GMEM_MOVEABLE , dwDataSize ); ! 426: /* GMEM_SHARE is not needed on 32 bits */ ! 427: if (!hData) ! 428: { ! 429: MessageBox(hwndApp, "Out of memory.", ! 430: NULL, MB_OK | MB_ICONEXCLAMATION); ! 431: mmioClose(hmmio, 0); ! 432: return; ! 433: } ! 434: lpData = GlobalLock(hData); ! 435: if (!lpData) ! 436: { ! 437: MessageBox(hwndApp, "Failed to lock memory for data chunk.", ! 438: NULL, MB_OK | MB_ICONEXCLAMATION); ! 439: GlobalFree( hData ); ! 440: mmioClose(hmmio, 0); ! 441: return; ! 442: } ! 443: ! 444: /* Read the waveform data subchunk. ! 445: */ ! 446: if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != (LONG) dwDataSize) ! 447: { ! 448: MessageBox(hwndApp, "Failed to read data chunk.", ! 449: NULL, MB_OK | MB_ICONEXCLAMATION); ! 450: GlobalUnlock( hData ); ! 451: GlobalFree( hData ); ! 452: mmioClose(hmmio, 0); ! 453: return; ! 454: } ! 455: ! 456: /* We're done with the file, close it. ! 457: */ ! 458: mmioClose(hmmio, 0); ! 459: ! 460: /* Reverse the sound for playing. ! 461: */ ! 462: hpch1 = lpData; ! 463: hpch2 = lpData + dwDataSize - 1; ! 464: while (hpch1 < hpch2) ! 465: { ! 466: Interchange( hpch1, hpch2, wBlockSize ); ! 467: hpch1 += wBlockSize; ! 468: hpch2 -= wBlockSize; ! 469: } ! 470: ! 471: /* Allocate a waveform data header. The WAVEHDR must be ! 472: * globally allocated and locked. ! 473: */ ! 474: hWaveHdr = GlobalAlloc(GMEM_MOVEABLE, (DWORD) sizeof(WAVEHDR)); ! 475: if (!hWaveHdr) ! 476: { ! 477: GlobalUnlock( hData ); ! 478: GlobalFree( hData ); ! 479: MessageBox(hwndApp, "Not enough memory for header.", ! 480: NULL, MB_OK | MB_ICONEXCLAMATION); ! 481: return; ! 482: } ! 483: lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr); ! 484: if (!lpWaveHdr) ! 485: { ! 486: GlobalUnlock( hData ); ! 487: GlobalFree( hData ); ! 488: GlobalFree( hWaveHdr ); ! 489: MessageBox(hwndApp, "Failed to lock memory for header.", ! 490: NULL, MB_OK | MB_ICONEXCLAMATION); ! 491: return; ! 492: } ! 493: ! 494: /* Allocate and set up instance data for waveform data block. ! 495: * This information is needed by the routine that frees the ! 496: * data block after it has been played. ! 497: */ ! 498: hWaveInst = GlobalAlloc(GMEM_MOVEABLE, (DWORD) sizeof(WAVEHDR)); ! 499: if (!hWaveInst) ! 500: { ! 501: GlobalUnlock( hData ); ! 502: GlobalFree( hData ); ! 503: GlobalUnlock( hWaveHdr ); ! 504: GlobalFree( hWaveHdr ); ! 505: MessageBox(hwndApp, "Not enough memory for instance data.", ! 506: NULL, MB_OK | MB_ICONEXCLAMATION); ! 507: return; ! 508: } ! 509: lpWaveInst = (LPWAVEINST) GlobalLock(hWaveInst); ! 510: if (!lpWaveInst) ! 511: { ! 512: GlobalUnlock( hData ); ! 513: GlobalFree( hData ); ! 514: GlobalUnlock( hWaveHdr ); ! 515: GlobalFree( hWaveHdr ); ! 516: GlobalFree( hWaveInst ); ! 517: MessageBox(hwndApp, "Failed to lock memory for instance data.", ! 518: NULL, MB_OK | MB_ICONEXCLAMATION); ! 519: return; ! 520: } ! 521: lpWaveInst->hWaveInst = hWaveInst; ! 522: lpWaveInst->hWaveHdr = hWaveHdr; ! 523: lpWaveInst->hWaveData = hData; ! 524: ! 525: /* Set up WAVEHDR structure and prepare it to be written to wave device. ! 526: */ ! 527: lpWaveHdr->lpData = lpData; ! 528: lpWaveHdr->dwBufferLength = dwDataSize; ! 529: lpWaveHdr->dwFlags = 0L; ! 530: lpWaveHdr->dwLoops = 0L; ! 531: lpWaveHdr->dwUser = (DWORD) lpWaveInst; ! 532: if(waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR))) ! 533: { ! 534: GlobalUnlock( hData ); ! 535: GlobalFree( hData ); ! 536: GlobalUnlock( hWaveHdr ); ! 537: GlobalFree( hWaveHdr ); ! 538: GlobalUnlock( hWaveInst ); ! 539: GlobalFree( hWaveInst ); ! 540: MessageBox(hwndApp, "Unable to prepare wave header.", ! 541: NULL, MB_OK | MB_ICONEXCLAMATION); ! 542: ! 543: return; ! 544: } ! 545: ! 546: /* Then the data block can be sent to the output device. ! 547: */ ! 548: { MMRESULT mmResult; ! 549: mmResult = waveOutWrite(hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); ! 550: if (mmResult != 0) ! 551: { ! 552: waveOutUnprepareHeader( hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); ! 553: GlobalUnlock( hData ); ! 554: GlobalFree( hData ); ! 555: MessageBox(hwndApp, "Failed to write block to device", ! 556: NULL, MB_OK | MB_ICONEXCLAMATION); ! 557: return; ! 558: } ! 559: } ! 560: ! 561: /* Disable input to the button controls. ! 562: */ ! 563: EnableWindow(hwndPlay, FALSE); ! 564: EnableWindow(hwndQuit, FALSE); ! 565: } ! 566: ! 567: /* Interchange - Interchanges two samples at the given positions. ! 568: * ! 569: * Params: hpchPos1 - Points to one sample. ! 570: * hpchPos2 - Points to the other sample. ! 571: * wLength - The length of a sample in bytes. ! 572: * ! 573: * Return: void ! 574: */ ! 575: void Interchange(HPSTR hpchPos1, HPSTR hpchPos2, unsigned uLength) ! 576: { ! 577: unsigned uPlace; ! 578: BYTE bTemp; ! 579: ! 580: for (uPlace = 0; uPlace < uLength; uPlace++) ! 581: { ! 582: bTemp = hpchPos1[uPlace]; ! 583: hpchPos1[uPlace] = hpchPos2[uPlace]; ! 584: hpchPos2[uPlace] = bTemp; ! 585: } ! 586: } ! 587: ! 588: VOID cleanup(LPWAVEINST lpWaveInst) ! 589: { ! 590: GlobalUnlock( lpWaveInst->hWaveData ); ! 591: GlobalFree( lpWaveInst->hWaveData ); ! 592: GlobalUnlock( lpWaveInst->hWaveHdr ); ! 593: GlobalFree( lpWaveInst->hWaveHdr ); ! 594: GlobalUnlock( lpWaveInst->hWaveInst ); ! 595: GlobalFree( lpWaveInst->hWaveInst ); ! 596: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.