15.¿Ï¼º ¿¹Á¦

¿©±â±îÁö ¿Ï¼ºµÈ Àüü ¼Ò½º´Â ´ÙÀ½°ú °°´Ù. ÃÖÁ¾ °á°ú¸¸ ºÐ¼®ÇØ º¼ »ç¶÷Àº ÀÌ Äڵ带 µð¹ö±ëÇϸ鼭 ¿¬±¸ÇØ º¸¸é µÈ´Ù. 200ÁÙ ¾à°£ ³Ñ´Â ±æÀÌÁö¸¸ ÄÚµåÀÇ ³í¸®´Â ³ª¸§ º¹ÀâÇÑ ÆíÀ̾ ÀÌ ¿¹Á¦¸¸ º¸¾Æ¼­´Â È帧À» ºÐ¼®Çϱ⠽±Áö ¾Ê´Ù.

 

#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 = 10;

const int bufsize = 17600;

const int pktsize = 10000;

WAVEHDR hdr[hdrnum];

char samplebuf[hdrnum][bufsize];

long availhdr;

int nowhdr;

char pktbuf[pktsize];

char* pktptr;

char* bufptr;

bool isPlaying;

HANDLE hThread;

bool isPause;

bool doExit;

 

int PlayWave(LPCTSTR song);

DWORD WINAPI PlayThread(LPVOID temp);

 

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;

           OPENFILENAME OFN;

           TCHAR Path[MAX_PATH] = TEXT("");

 

           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:

                        memset(&OFN, 0, sizeof(OPENFILENAME));

                        OFN.lStructSize = sizeof(OPENFILENAME);

                        OFN.hwndOwner = hWndMain;

                        OFN.lpstrFilter = TEXT("Wave ÆÄÀÏ(*.wav)\0*.wav\0¸ðµç ÆÄÀÏ(*.*)\0*.*\0");

                        OFN.lpstrFile = Path;

                        OFN.nMaxFile = MAX_PATH;

                        if (GetOpenFileName(&OFN) != 0) {

                                     PlayWave(Path);

                        }

                        return 0;

           case WM_RBUTTONDOWN:

                        if (isPlaying) {

                                     if (isPause) {

                                                  waveOutRestart(hWaveDev);

                                                  isPause = false;

                                     } else {

                                                  waveOutPause(hWaveDev);

                                                  isPause = true;

                                     }

                        }

                        return 0;

           case WM_MOUSEWHEEL:

                        DWORD vol;

                        int left, right, delta;

 

                        waveOutGetVolume(hWaveDev, &vol);

                        left = LOWORD(vol);

                        right = HIWORD(vol);

                        delta = 0x1000;

                        if ((short)HIWORD(wParam) < 0) delta *= -1;

                        left = max(min(left + delta, 0xffff), 0);

                        right = max(min(right + delta, 0xffff), 0);

                        vol = MAKELONG(left, right);

                        waveOutSetVolume(hWaveDev, vol);

                        return 0;

           case MM_WOM_DONE:

                        InterlockedIncrement(&availhdr);

                        return 0;

           case WM_DESTROY:

                        if (hThread) CloseHandle(hThread);

                        PostQuitMessage(0);

                        return 0;

           }

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

}

 

int PlayWave(LPCTSTR song)

{

           if (isPlaying) {

                        waveOutReset(hWaveDev);

                        doExit = true;

                        WaitForSingleObject(hThread, INFINITE);

                        MSG Message;

                        while (PeekMessage(&Message, NULL, MM_WOM_DONE, MM_WOM_DONE, PM_REMOVE)) { ; }

           }

 

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

                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

           if (hFile == INVALID_HANDLE_VALUE) {

                        return 0;

           }

 

           isPlaying = true;

           isPause = false;

           doExit = false;

           availhdr = hdrnum;

           nowhdr = 0;

 

           DWORD ThreadID;

           if (hThread) CloseHandle(hThread);

           hThread = CreateThread(NULL, 0, PlayThread, NULL, 0, &ThreadID);

           return 0;

}

 

DWORD WINAPI PlayThread(LPVOID temp) {

           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_PTR)hWndMain, 0, CALLBACK_WINDOW);

           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 = DWORD(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 = int(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) {

                                                  if (doExit) goto end;

                                                  Sleep(20);

                                     }

                                     if (doExit) goto end;

 

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

                                     bufptr = samplebuf[nowhdr];

                        }

           }

 

           end:

 

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

           CloseHandle(hFile);

           isPlaying = false;

           return 0;

}

 

»ç¿îµå¸¦ Àç»ýÇÏ´Â ±âº» ±â´ÉÀº ¿Ï·áÇßÁö¸¸ µðÀÚÀÎÀ̳ª ÆíÀÇ ±â´ÉÀº ¸¹ÀÌ ºÎÁ·ÇÏ´Ù. ´õ ¸¹Àº ÆíÀÇ ±â´ÉÀ» ¾ó¸¶µçÁö ³ÖÀ» ¼ö ÀÖ´Ù.

 

¢º »ç¿îµå ÆÄÀÏ Á¤º¸¸¦ È­¸é¿¡ º¸¿© ÁØ´Ù.

¢º ÇöÀç Àç»ý À§Ä¡¸¦ º¸¿© ÁÖ°í ÀÓÀÇÀÇ À§Ä¡·Î À̵¿ÇÑ´Ù.

¢º ¿©·¯ °³ÀÇ ÆÄÀÏÀ» ÇѲ¨¹ø¿¡ ¿­¾î ³õ°í ¸ñ·ÏÀÇ ÆÄÀÏÀ» ¼ø¼­´ë·Î Àç»ýÇÑ´Ù.

¢º »ùÇÃÀÇ ³ô³·ÀÌ¿¡ µû¶ó ¸ÚÁø ±×·¡ÇÈ ÀÌÄ÷¶óÀÌÀú¸¦ º¸¿© ÁØ´Ù.

¢º Àç»ý ¼Óµµ¸¦ Á¶Á¤ÇÑ´Ù.

 

±×·¯³ª ºñ¾ÐÃà Æ÷¸Ë¸¸ ´Ù·ç°í ÀÖ¾î À½¾Ç °¨»ó¿ëÀ¸·Î ¾²±â´Â ºÎÁ·ÇÏ´Ù. ¾ÐÃà Æ÷¸Ëµµ ´Ù·ê ¼ö ÀÖ°í »ó±âÀÇ ±â´ÉÀ» ´Ù ±¸ÇöÇϸé MP3 Ç÷¹À̾ µÇ´Â ¼ÀÀÌ´Ù.

 

ÀÌ»óÀ¸·Î ºÎÁ·ÇÑ °­Á¸¦ ¸¶Ä¨´Ï´Ù. ÀÌÇظ¦ À§ÇÑ ±³À°¿ë ¿¹Á¦ÀÌ´Ù º¸´Ï ÃÖ´ëÇÑ ¼³¸íÀûÀÎ Äڵ带 ÀÛ¼ºÇßÀ¸¸ç ±×·¯´Ù º¸´Ï ÇÁ·ÎÁ§Æ®¿¡ Àç»ç¿ëÇϱ⿡´Â ÀûÇÕÇÏÁö ¾Ê½À´Ï´Ù. ³í¸®¸¦ ÀÌÇØÇÑ ÈÄ ½ÇÁ¦ ÇÁ·ÎÁ§Æ®¿¡ Àû¿ëÇÒ ¶§´Â ÃëÇâ¿¡ ¸Â°Ô ¹Ù²Ù¾î ¾²½Ã±â ¹Ù¶ø´Ï´Ù. ±ÞÇÏ°Ô ¸¸µå´À¶ó ¾ÈÁ¤¼ºµµ ÃæºÐÈ÷ °ËÁõÇÏÁö ¸øÇߴµ¥ Ä¡¸íÀûÀÎ ¹ö±×°¡ º¸ÀÌ¸é ¾Ë·Á ÁֽʽÿÀ. ¾ðÁ¨°¡ ½Ã°£ÀÌ Çã¶ôÇÏ¸é ´õ À߸øµÈ ³»¿ëÀ» ¼öÁ¤ÇÏ°í ±â´ÉÀ» ´õ Ãß°¡ÇÑ °­Á¸¦ ÀÛ¼ºÇÏ°Ú½À´Ï´Ù. °¨»çÇÕ´Ï´Ù.