11.±×·¡ÇÈ È¯°æ

ÄÜ¼Ö È¯°æÀº ÄÚµåÀÇ È帧ÀÌ Á÷¼±ÀûÀ̾ ÇнÀ¿ëÀ¸·Î Æí¸®ÇÏ´Ù. ±×·¯³ª Äڵ常 ½ÇÇàÇØ º¼ ¼ö ÀÖÀ» »Ó »ç¿ëÀÚ¿Í »óÈ£ÀÛ¿ëÇϱ⠾î·Æ´Ù. ÆÄÀÏÀ» ¼±ÅÃÇÒ ¼ö ¾ø°í ±â´ÉÀ» Á¦¾îÇÒ UIµµ ¾ø´Ù. ½Ç¿ëÀûÀÎ ÇÁ·Î±×·¥À» ¸¸µé·Á¸é ¿ª½Ã ±×·¡ÇÈ È¯°æÀ̾î¾ß ÇÑ´Ù.

ÄÜ¼Ö È¯°æ¿¡¼­ ÀÌ·ÐÀº ´Ù »ìÆì ºÃÀ¸´Ï ÀÌÁ¦ ±×·¡ÇÈ È¯°æÀ¸·Î ¿Å°Ü ¿Í º¸ÀÚ. WaveTestWin À̸§À¸·Î Win32 ÇÁ·ÎÁ§Æ®¸¦ »ý¼ºÇÑ´Ù. Ưº°ÇÑ ¿É¼ÇÀ» Á¶Á¤ÇÒ ÇÊ¿ä ¾øÀÌ µðÆúÆ® ¼¼ÆÃÀ» »ç¿ëÇÏ¸é µÈ´Ù. ¾Õ ¿¹Á¦ÀÇ Äڵ带 ±×·¡ÇÈ È¯°æÀÇ ÇÁ·ÎÁ§Æ®·Î °¡Á®¿Â´Ù.

 

#include <windows.h>

 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

HINSTANCE g_hInst;

HWND hWndMain;

LPCTSTR lpszClass = TEXT("WaveTestWin");

 

#pragma comment(lib, "winmm.lib")

 

HWAVEOUT hWaveDev;

HANDLE hFile;

DWORD dwRead;

WAVEFORMATEX wf;

const int hdrnum = 3;

const int bufsize = 3000;

const int pktsize = 2000;

WAVEHDR hdr[hdrnum];

char samplebuf[hdrnum][bufsize];

long availhdr = hdrnum;

int nowhdr = 0;

char pktbuf[pktsize];

char* pktptr;

char* bufptr;

 

void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);

int PlayWave(LPCTSTR song);

 

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance

           , LPSTR lpszCmdParam, int nCmdShow)

{

           HWND hWnd;

           MSG Message;

           WNDCLASS WndClass;

           g_hInst = hInstance;

 

           WndClass.cbClsExtra = 0;

           WndClass.cbWndExtra = 0;

           WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

           WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);

           WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

           WndClass.hInstance = hInstance;

           WndClass.lpfnWndProc = WndProc;

           WndClass.lpszClassName = lpszClass;

           WndClass.lpszMenuName = NULL;

           WndClass.style = CS_HREDRAW | CS_VREDRAW;

           RegisterClass(&WndClass);

 

           hWnd = CreateWindow(lpszClass, lpszClass, WS_OVERLAPPEDWINDOW,

                        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

                        NULL, (HMENU)NULL, hInstance, NULL);

           ShowWindow(hWnd, nCmdShow);

 

           while (GetMessage(&Message, NULL, 0, 0)) {

                        TranslateMessage(&Message);

                        DispatchMessage(&Message);

           }

           return (int)Message.wParam;

}

 

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)

{

           HDC hdc;

           PAINTSTRUCT ps;

 

           switch (iMessage) {

           case WM_CREATE:

                        hWndMain = hWnd;

                        return 0;

           case WM_PAINT:

                        hdc = BeginPaint(hWnd, &ps);

                        LPCTSTR usage;

                        usage = L"¿ÞÂÊ Å¬¸¯:ÆÄÀÏ Àç»ý";

                        TextOut(hdc, 10, 10, usage, lstrlen(usage));

                        EndPaint(hWnd, &ps);

                        return 0;

           case WM_LBUTTONDOWN:

                        PlayWave(TEXT("c:\\Temp\\takeonme.wav"));

                        return 0;

           case WM_DESTROY:

                        PostQuitMessage(0);

                        return 0;

           }

           return(DefWindowProc(hWnd, iMessage, wParam, lParam));

}

 

void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {

           if (uMsg == WOM_DONE) {

                        InterlockedIncrement(&availhdr);

           }

}

 

int PlayWave(LPCTSTR song)

{

           hFile = CreateFile(song, GENERIC_READ, FILE_SHARE_READ, NULL,

                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

           if (hFile == INVALID_HANDLE_VALUE) {

                        return -1;

           }

 

           wf.cbSize = sizeof(WAVEFORMATEX);

           wf.wFormatTag = WAVE_FORMAT_PCM;

           SetFilePointer(hFile, 22, NULL, SEEK_SET); ReadFile(hFile, &wf.nChannels, 2, &dwRead, NULL);

           SetFilePointer(hFile, 24, NULL, SEEK_SET); ReadFile(hFile, &wf.nSamplesPerSec, 4, &dwRead, NULL);

           SetFilePointer(hFile, 34, NULL, SEEK_SET); ReadFile(hFile, &wf.wBitsPerSample, 2, &dwRead, NULL);

           wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample / 8;

           wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;

 

           waveOutOpen(&hWaveDev, WAVE_MAPPER, &wf, (DWORD)waveOutProc, 0, CALLBACK_FUNCTION);

           SetFilePointer(hFile, 44, NULL, SEEK_SET);

 

           for (int i = 0; i < hdrnum; i++) {

                        hdr[i].lpData = samplebuf[i];

           }

 

           bufptr = samplebuf[nowhdr];

 

           for (;;) {

                        ReadFile(hFile, pktbuf, pktsize, &dwRead, NULL);

                        if (dwRead == 0) {

                                     hdr[nowhdr].dwBufferLength = bufptr - samplebuf[nowhdr];

                                     waveOutPrepareHeader(hWaveDev, &hdr[nowhdr], sizeof(WAVEHDR));

                                     waveOutWrite(hWaveDev, &hdr[nowhdr], sizeof(WAVEHDR));

                                     InterlockedDecrement(&availhdr);

                                     break;

                        }

 

                        pktptr = pktbuf;

                        int remainpkt = dwRead;

 

                        for (;;) {

                                     int remainbuf = bufsize - (bufptr - samplebuf[nowhdr]);

 

                                     if (remainpkt < remainbuf) {

                                                  memcpy(bufptr, pktptr, remainpkt);

                                                  bufptr += remainpkt;

                                                  break;

                                     }

 

                                     memcpy(bufptr, pktptr, remainbuf);

 

                                     remainpkt -= remainbuf;

                                     pktptr += remainbuf;

 

                                     hdr[nowhdr].dwBufferLength = bufsize;

                                     waveOutPrepareHeader(hWaveDev, &hdr[nowhdr], sizeof(WAVEHDR));

                                     waveOutWrite(hWaveDev, &hdr[nowhdr], sizeof(WAVEHDR));

 

                                     InterlockedDecrement(&availhdr);

 

                                     while (availhdr == 0) Sleep(20);

 

                                     if (++nowhdr == hdrnum) nowhdr = 0;

                                     bufptr = samplebuf[nowhdr];

                        }

           }

 

           while (waveOutClose(hWaveDev) == WAVERR_STILLPLAYING) { Sleep(10); }

           CloseHandle(hFile);

           return 0;

}

 

À©µµ¿ì¸¦  »ý¼ºÇÏ°í ¸Þ½ÃÁö ·çÇÁ¸¦ µ¹¸®±â À§ÇØ WinMain, WndProc ÇÔ¼ö°¡ Ãß°¡µÇ¾ú´Ù. WM_PAINT¿¡¼­ °£´ÜÇÑ ¾È³» ¸Þ½ÃÁö¸¦ Ãâ·ÂÇÏ°í ¸¶¿ì½º ¿ÞÂÊ ¹öÆ°À» ´©¸£¸é PlayWave ÇÔ¼ö¸¦ È£ÃâÇÏ¿© »ç¿îµå¸¦ Àç»ýÇÑ´Ù. ³ª¸ÓÁö ÄÚµå´Â ÄܼÖÀÇ Äڵ带 ±×´ë·Î °¡Á®¿Â °ÍÀ̸ç À¯ÀÏÇÏ°Ô ¹Ù²Û °ÍÀº ±×·¡ÇÈ È¯°æ¿¡¼­´Â ¾µ ¼ö ¾ø´Â puts ¿¡·¯ È£Ãâ¹®À» Á¦°ÅÇÑ °Í »ÓÀÌ´Ù. ¸Þ½ÃÁö ¹Ú½º Á¤µµ·Î ¹Ù²Ù¸é Àû´çÇÏ´Ù.

½ä··ÇÑ À©µµ¿ì°¡ Çϳª ¿­¸®´Âµ¥ ¸¶¿ì½º ¿ÞÂÊ ¹öÆ°À» ´©¸£¸é »ç¿îµå ÆÄÀÏÀ» Àç»ýÇÑ´Ù. Äְܼú ¶È°°ÀÌ µ¿ÀÛÇÏÁö¸¸ ¾ÆÁ÷ Á¦´ë·Î µÈ ±×·¡ÇÈ ÇÁ·Î±×·¥Àº ¾Æ´Ï´Ù. ´ÜÀÏ ½º·¹µå¿©¼­ Àç»ýÁß¿¡ À©µµ¿ì¸¦ ¿òÁ÷ÀÏ ¼ö ¾øÀ¸¸ç ½ÉÁö¾î Á¾·áµµ ÇÒ ¼ö ¾ø´Ù.

PlayWave ÇÔ¼ö°¡ CPU¸¦ µ¶Â÷ÁöÇÏ°í ÀÖÀ¸´Ï ´Ù¸¥ ¸Þ½ÃÁö¸¦ ó¸®ÇÒ °Ü¸¦ÀÌ ¾ø±â ¶§¹®ÀÌ´Ù. ´ÙÇàÈ÷ »ç¿îµå Àç»ýÀÌ ³¡³ª¸é ´Ù½Ã ¸Þ½ÃÁö¸¦ ó¸®ÇÒ ¼ö ÀÖ´Ù. À©µµ¿ì´Â Äְܼú´Â ´Þ¸® À̺¥Æ® µå¸®ºì ¹æ½ÄÀ¸·Î µ¿ÀÛÇÏ¿© Çѹø¿¡ ³Ê¹« ±ä ÀÛ¾÷À» Çؼ­´Â ¾ÈµÈ´Ù. À©µµ¿ì ±¸Á¶¿¡ ¾î¿ï¸®´Â Äڵ带 ÀÛ¼ºÇØ º¸ÀÚ.