ÄÜ¼Ö È¯°æÀº ÄÚµåÀÇ È帧ÀÌ Á÷¼±ÀûÀÌ¾î¼ ÇнÀ¿ëÀ¸·Î Æí¸®ÇÏ´Ù. ±×·¯³ª
Äڵ常 ½ÇÇàÇØ º¼ ¼ö ÀÖÀ» »Ó »ç¿ëÀÚ¿Í »óÈ£ÀÛ¿ëÇϱ⠾î·Æ´Ù. ÆÄÀÏÀ» ¼±ÅÃÇÒ ¼ö ¾ø°í ±â´ÉÀ» Á¦¾îÇÒ 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¸¦
µ¶Â÷ÁöÇÏ°í ÀÖÀ¸´Ï ´Ù¸¥ ¸Þ½ÃÁö¸¦ ó¸®ÇÒ °Ü¸¦ÀÌ ¾ø±â ¶§¹®ÀÌ´Ù. ´ÙÇàÈ÷ »ç¿îµå Àç»ýÀÌ ³¡³ª¸é ´Ù½Ã ¸Þ½ÃÁö¸¦
ó¸®ÇÒ ¼ö ÀÖ´Ù. À©µµ¿ì´Â Äְܼú´Â ´Þ¸® À̺¥Æ® µå¸®ºì ¹æ½ÄÀ¸·Î µ¿ÀÛÇÏ¿© Çѹø¿¡ ³Ê¹« ±ä ÀÛ¾÷À» Çؼ´Â
¾ÈµÈ´Ù. À©µµ¿ì ±¸Á¶¿¡ ¾î¿ï¸®´Â Äڵ带 ÀÛ¼ºÇØ º¸ÀÚ.