- 발표ì—� ê¼ ë“¤ì–´ê°€ì•¼ í• ê²ƒë“¤
- 프로그램�서 사운드 재�� 어떻게 하는가?
- 프로그램�서 ��� 재�� 어떻게 하는가?
- 프로그램�서 사운드 재�� 어떻게 하는가?
1. 사운드 연주 ¶
MFC는 멀티미디어를 위한 별ë�„ì�˜ í�´ëž˜ìŠ¤ë¥¼ ì œê³µí•˜ì§€ 않는다. Win32 API함수 ì°¨ì›�ì—�서 멀티미디어를 ì§€ì›�하기 때문ì—� MFCì—�서는 별ë�„ì�˜ í�´ëž˜ìŠ¤ë¡œ 만들어 놓지 않ì�€ 것ì�´ë‹¤.
ìš°ì„ ì‚¬ìš´ë“œë¥¼ 연주하는 API함수를 ë³´ìž�.
ìš°ì„ ì‚¬ìš´ë“œë¥¼ 연주하는 API함수를 ë³´ìž�.
~cpp BOOL PlaySound(LPCSTR pszSound, HMODULE hmod, DWORD fdwSound);
pszSound : ì—°ì£¼í• ì‚¬ìš´ë“œ 파ì�¼ì�˜ ì�´ë¦„. 파ì�¼ì�˜ 경로를 ë„£ì�„ ë�” 수ë�„ 있다.
hmod : 리소스ì—� 있는 Wave파ì�¼ì�„ ì—°ì£¼í• ê²½ìš° 리소스를 가진 실행파ì�¼ì�˜ 핸들ì�¸ë�°, ê·¸ 외ì�˜ 경우는 NULL로 준다.
fdwSound : 사운드ì�˜ 연주방ì‹�ê³¼ ì—°ì£¼í• ì‚¬ìš´ë“œì�˜ 종류를 ì •ì�˜í•˜ëŠ” 플래그ì�´ë‹¤. ì�´ê²ƒì—� ë”°ë�¼ 첫 번째, ë‘� 번째 ì�¸ìˆ˜ì�˜ í•´ì„� ë°©ì‹�ì�´ 달ë�¼ì§„다. 여러 플래그 중 몇 가지만 알아보ìž�.
- SND_FILENAME : 첫 번째 �수� pszSound는 사운드 파�� �름�다.
- SND_ASYNC : 비ë�™ê¸°í™”ë�œ 연수를 한다. 연주시작 후 바로 리턴하므로 다른 작업ì�„ 바로 ì‹œìž‘í• ìˆ˜ 있다.
- SND_LOOP : ì§€ì •í•œ 사운드를 반복ì �으로 계ì†� 연주한다. ì�´ 플래그는 반드시 SND_ASYNC와 함께 사용ë�˜ì–´ì•¼ 한다.
- SND_SYNC : ë�™ê¸°í™”ë�œ 연주를 한다. 사운드 파ì�¼ì�˜ 연주가 ì™„ì „ížˆ ë��나기 ì „ì—�는 리턴하지 않는다.
- SND_ASYNC : 비ë�™ê¸°í™”ë�œ 연수를 한다. 연주시작 후 바로 리턴하므로 다른 작업ì�„ 바로 ì‹œìž‘í• ìˆ˜ 있다.
- SND_LOOP : ì§€ì •í•œ 사운드를 반복ì �으로 계ì†� 연주한다. ì�´ 플래그는 반드시 SND_ASYNC와 함께 사용ë�˜ì–´ì•¼ 한다.
- SND_SYNC : ë�™ê¸°í™”ë�œ 연주를 한다. 사운드 파ì�¼ì�˜ 연주가 ì™„ì „ížˆ ë��나기 ì „ì—�는 리턴하지 않는다.
ì˜ˆì œ) AppWizard를 사용하여 Soundë�¼ëŠ” ì�´ë¦„으로 SDI 프로ì �트를 ë§Œë“ ë‹¤.
ë·°ì—� WM_LBUTTONDOWN메시지ì�˜ 핸들러를 ë§Œë“¤ê³ OnLButtonDown 핸들러ì—� 다ì�Œê³¼ ê°™ì�´ 코드를 작성한다.
ë·°ì—� WM_LBUTTONDOWN메시지ì�˜ 핸들러를 ë§Œë“¤ê³ OnLButtonDown 핸들러ì—� 다ì�Œê³¼ ê°™ì�´ 코드를 작성한다.
~cpp
#include "mmsystem.h"
void CSoundView::.....
{
PlaySound("Battle.wav", NULL, SND_SYNC);
CView:....
}
PlaySound 함수를 ì‚¬ìš©í•˜ë ¤ë©´ mmsystem.h 파ì�¼ì�„ ë¨¼ì € include 해주어야 í•˜ê³ ,
Project/ Settings/Link íƒì—�서 winmm.lib를 ë§�í�¬í•´ 주어야 한다.
ê·¸ 후 컴파ì�¼í•˜ê³ 실행한 후 작업ì˜�ì—ì�„ 왼쪽 마우스 버튼으로 누르면 소리가 ë‚ ê²ƒì�´ë‹¤. 시스템ì—� 사운드카드가 장착ë�˜ì–´ 있어야 하며 ê°™ì�€ ë””ë ‰í† ë¦¬ì—� Battle.wavë�¼ëŠ” 파ì�¼ì�´ 있어야 í• ê²ƒì�´ë‹¤.Project/ Settings/Link íƒì—�서 winmm.lib를 ë§�í�¬í•´ 주어야 한다.
1-2) 비�기 연주
앞서 ë§Œë“ ì˜ˆì œë¥¼ ë³´ë©´ PlaySound 함수는 사운드 파ì�¼ 연주가 ì™„ì „ížˆ 종료ë�˜ê¸° ì „ì—�는 리턴하지 않으므로 연주중ì�¸ ë�™ì•ˆì�€ ì–´ë–¤ ì�¼ë�„ í• ìˆ˜ 없다. ì�´ëŸ° 방법ì�„ ë�™ê¸°í™” ë°©ì‹�ì�´ë�¼ê³ 한다.
반대로 PlaySound함수가 연주를 시작해 ë†“ê³ ê³§ë°”ë¡œ 리턴하는 비ë�™ê¸° 연주 ë°©ì‹�ì�´ 있다.
ì�´ë²ˆì—�는 SND_LOOP 플래그를 사용하여 작성해 ë³´ê³ , WM_RBUTTONDOWN 메시지ì�˜ 핸들러ë�„ ê°™ì�´ 만들어보ìž�.
반대로 PlaySound함수가 연주를 시작해 ë†“ê³ ê³§ë°”ë¡œ 리턴하는 비ë�™ê¸° 연주 ë°©ì‹�ì�´ 있다.
ì�´ë²ˆì—�는 SND_LOOP 플래그를 사용하여 작성해 ë³´ê³ , WM_RBUTTONDOWN 메시지ì�˜ 핸들러ë�„ ê°™ì�´ 만들어보ìž�.
~cpp
void CSoundView::OnLB.........
{
PlaySound("Battle.wav", NULL, SND_ASYNC | SND_LOOP);
CView:....
}
void CSoundView::OnRB......
{
PlaySound(NULL, NULL, 0);
CView:....
}
SND_LOOP 플래그를 ì§€ì •í•˜ë©´ 반복ì �ì�¸ 효과ì�Œì�´ë‚˜ ë°°ê²½ì�Œì•…ì�„ 연주하는 등ì�˜ ì„¤ì •ì�„ í• ìˆ˜ 있ì�„ 것ì�´ë‹¤. 연주를 ì¤‘ì§€ì‹œí‚¤ë ¤ë©´ PlaySound 함수ì�˜ 첫 번째 ì�¸ìˆ˜ë¥¼ NULL로 하여 다시 호출해 주면 ë�œë‹¤. ë”°ë�¼ì„œ, 오른쪽 마우스 버튼ì�„ 누르면 연주가 중지ë� 것ì�´ë‹¤. 주ì�˜í• 것ì�€ SND_LOOP 플래그는 반드시 SND_ASYNC와 함께 사용해야 한다. 만약 ë�™ê¸°í™” 연주방ì‹�으로 반복연주를 하면 무한 루프로 ë¹ ì ¸ë²„ë¦´ 위험ì�´ 있다.
1-3) 리소스ì�˜ Wave 연주사운드 파ì�¼ì�„ 연주하는 것ì�€ 사용하기는 간단하지만 ì—°ì£¼í• ë•Œë§ˆë‹¤ 디스í�¬ì—�서 사운드 파ì�¼ì�„ ì�½ì–´ì™€ì•¼ 하므로 ë°˜ì�‘ ì†�ë�„ê°€ ëŠ�리다. ë”°ë�¼ì„œ ì�´ 경우ì—�는 사운드 파ì�¼ì�„ 리소스ì—� í�¬í•¨ì‹œì¼œ ë†“ê³ ë¦¬ì†ŒìŠ¤ì—�서 ì�½ì–´ì„œ 연주하는 방법으로 하는 것ì�´ 좋ì�„ 것ì�´ë‹¤.
앞ì—�서 ë§Œë“ ì˜ˆì œë¥¼ ìˆ˜ì •í•´ì„œ Battle.wav 파ì�¼ì�„ 실행파ì�¼ì—� í•©ì³�ë³´ìž�.
리소스 ë·°ì�˜ íŒ�업메뉴ì—�서 Import 메뉴í•목ì�„ ì„ íƒ�í•˜ê³ ë¦¬ì†ŒìŠ¤ì—� í�¬í•¨ì‹œí‚¤ê³ ìž� 하는 Wave 파ì�¼ì�„ ì„ íƒ�한다. 그러면 IDR_WAVE1ì�´ë�¼ëŠ” ID로 리소스ì—� 삽입ë� 것ì�´ë‹¤.
리소스ì—� í�¬í•¨ë�œ 사운드를 ì—°ì£¼í•˜ë ¤ë©´ PlaySoundì�˜ 세 번째 ì�¸ìˆ˜ì—� SND_RESOURCE 플래그를 ì£¼ê³ ì²« 번째 ì�¸ìˆ˜ì—� 리소스ì�˜ ID를 준다. ë‘� 번째 ì�¸ìˆ˜ì—�는 리소스를 가진 실행파ì�¼ì�˜ ì�¸ìŠ¤í„´ìŠ¤ 핸들ì�„ 주어야 하는ë�° MFCì—�서는 AfxGetInstanceHandle() ì „ì—함수로 ì�¸ìŠ¤í„´ìŠ¤ 핸들ì�„ êµ¬í• ìˆ˜ 있다. 다ì�Œê³¼ ê°™ì�´ 코드를 작성해 ë³´ìž�.
앞ì—�서 ë§Œë“ ì˜ˆì œë¥¼ ìˆ˜ì •í•´ì„œ Battle.wav 파ì�¼ì�„ 실행파ì�¼ì—� í•©ì³�ë³´ìž�.
리소스 ë·°ì�˜ íŒ�업메뉴ì—�서 Import 메뉴í•목ì�„ ì„ íƒ�í•˜ê³ ë¦¬ì†ŒìŠ¤ì—� í�¬í•¨ì‹œí‚¤ê³ ìž� 하는 Wave 파ì�¼ì�„ ì„ íƒ�한다. 그러면 IDR_WAVE1ì�´ë�¼ëŠ” ID로 리소스ì—� 삽입ë� 것ì�´ë‹¤.
리소스ì—� í�¬í•¨ë�œ 사운드를 ì—°ì£¼í•˜ë ¤ë©´ PlaySoundì�˜ 세 번째 ì�¸ìˆ˜ì—� SND_RESOURCE 플래그를 ì£¼ê³ ì²« 번째 ì�¸ìˆ˜ì—� 리소스ì�˜ ID를 준다. ë‘� 번째 ì�¸ìˆ˜ì—�는 리소스를 가진 실행파ì�¼ì�˜ ì�¸ìŠ¤í„´ìŠ¤ 핸들ì�„ 주어야 하는ë�° MFCì—�서는 AfxGetInstanceHandle() ì „ì—함수로 ì�¸ìŠ¤í„´ìŠ¤ 핸들ì�„ êµ¬í• ìˆ˜ 있다. 다ì�Œê³¼ ê°™ì�´ 코드를 작성해 ë³´ìž�.
~cpp
void CSoundView::OnLButtonDown(UINT nFlags, CPoint point)
{
PlaySound(MAKEINTRESOURCE(IDR_WAVE1), AfxGetInstanceHandle(), SND_RESOURCE | SND_ASYNC);
CView:OnLButtonDown(nFlags, point);
}
ì�´ë ‡ê²Œ 하면 실행파ì�¼ ì†�ì—� wav파ì�¼ì�´ í�¬í•¨ë�˜ì–´ Battle.wav파ì�¼ì�´ 없어ë�„ ì—°ì£¼í• ìˆ˜ 있게 ë�œë‹¤.
1-4) MCI (Media Control Interface)PlaySound함수는 메모리 í�¬ê¸°ì�˜ ì œí•œì�„ 받아서 1-2ë¶„ ì •ë�„ì�˜ 사운드 ë°–ì—� 낼 수 없다는 ì �, Wave형태만 ì§€ì›�한다는 ì �, ì—°ì£¼ê³¼ì •ì—� 사용ìž�ê°€ ê°œìž…í• ìˆ˜ 없다는 단ì �ì�´ 있다.
MCI는 멀티미디어 요소ì—� 대한 ì§€ì›�ì�„ 장치ë�…립ì �으로 ì œê³µí•˜ëŠ” ì�¼ì¢…ì�˜ ë�¼ì�´ë¸ŒëŸ¬ë¦¬ì�´ë‹¤. ì�´ê²ƒì�€ PlaySound 함수가 하지 못하는 여러 가지 ì�¼ì�„ í• ìˆ˜ 있지만, 사용 방법ì�€ 훨씬 ë�” 복잡하다.
MCI는 멀티미디어 요소ì—� 대한 ì§€ì›�ì�„ 장치ë�…립ì �으로 ì œê³µí•˜ëŠ” ì�¼ì¢…ì�˜ ë�¼ì�´ë¸ŒëŸ¬ë¦¬ì�´ë‹¤. ì�´ê²ƒì�€ PlaySound 함수가 하지 못하는 여러 가지 ì�¼ì�„ í• ìˆ˜ 있지만, 사용 방법ì�€ 훨씬 ë�” 복잡하다.
| |
2. ë�™ì˜�ìƒ� 재ìƒ� ¶
2-1) PlayAVI
MCI를 사용하면 ë�™ì˜�ìƒ�ë�„ 아주 쉽게 재ìƒ�í• ìˆ˜ 있다. AppWizard로 PlayAVIë�¼ëŠ” SDI 프로ì �트를 ë§Œë“¤ê³ WM_LBUTTONDOWN 메시지ì�˜ 핸들러와 WM_DESTROY 메시지ì�˜ 핸들러를 다ì�Œê³¼ ê°™ì�´ 작성한다.
MCI를 사용하면 ë�™ì˜�ìƒ�ë�„ 아주 쉽게 재ìƒ�í• ìˆ˜ 있다. AppWizard로 PlayAVIë�¼ëŠ” SDI 프로ì �트를 ë§Œë“¤ê³ WM_LBUTTONDOWN 메시지ì�˜ 핸들러와 WM_DESTROY 메시지ì�˜ 핸들러를 다ì�Œê³¼ ê°™ì�´ 작성한다.
~cpp
HWND hWndAVI=0;
void CPlayAVIView::OnLButtonDown...
{
if(hWndAVI) {
MCIWndClose(hWndAVI);
MCIWndDestroy(hWndAVI);
hWndAVI=0;
}
hWndAVI=MCIWndCreate(this->m_hWnd, AfxGetInstanceHandle(), 0, "cf3.avi");
if(hWndAVI) {
MCIWndPlay(hWndAVI);
}
CView::OnLButtonDown(nFlags, point);
}
void CPlayAVIView::OnDestroy()
{
CView::OnDestroy();
MCIWndDestroy(hWndAVI);
}
��� 연주는 Video fot window ��브러리를 사용하므로 뷰�서 vfw.h를 ��루드 해 주어야 한다.
~cpp #include "PlayAVIDoc.h" #include "PlayAVIView.h" #include <vfw.h>
ë˜�한 프로ì �트ì—�서 ì�´ ë�¼ì�´ë¸ŒëŸ¬ë¦¬ë¥¼ ì‚¬ìš©í• ìˆ˜ 있ë�„ë¡� Project/Settings/Link íƒì—� vfw32.lib를 추가한다. ê·¸ë¦¬ê³ ë�™ì˜�ìƒ� 파ì�¼ì�„ 프로ì �트 ë””ë ‰í† ë¦¬ì—� 넣어ë‘�ë©´ ë�œë‹¤.
MCIWnd 윈ë�„우는 마우스 왼쪽 버튼ì�„ 눌르면 만들어진다. ê·¸ ì „ì—� hWndAVIê°€ ìœ íš¨í•˜ë©´ ë¨¼ì € MCIWnd를 닫는 작업부터 í•´ì£¼ê³ ìžˆë‹¤. MCIWnd를 만드는 함수는 MCIWndCreate 함수ì�´ë‹¤.~cpp HWND MCIWndCreate(HWND hwndParent, HINSTANCE hinstance, DWORD dwStyle, LPSTR szFile);
hWndParent: 부모윈ë�„우를 ì§€ì •í•œë‹¤. NULLì�¼ 경우, 별ë�„ì�˜ 윈ë�„우로 열린다.
hInstance: MCIWnd롤 사용하는 ì�¸ìŠ¤í„´ìŠ¤ 핸들ì�„ ì§€ì •í•œë‹¤.
dwStyle: MCIWndì�˜ 모양, ë�™ìž‘ë°©ì‹�등ì�„ ì„¤ì •í•˜ëŠ” 스타ì�¼(플래그)ì�´ë‹¤.
szFile: MCIWndìƒ�성시 ì˜¤í”ˆí• ìž¥ì¹˜, ë˜�는 AVI파ì�¼ì�„ ì§€ì •í•œë‹¤.
hInstance: MCIWnd롤 사용하는 ì�¸ìŠ¤í„´ìŠ¤ 핸들ì�„ ì§€ì •í•œë‹¤.
dwStyle: MCIWndì�˜ 모양, ë�™ìž‘ë°©ì‹�등ì�„ ì„¤ì •í•˜ëŠ” 스타ì�¼(플래그)ì�´ë‹¤.
szFile: MCIWndìƒ�성시 ì˜¤í”ˆí• ìž¥ì¹˜, ë˜�는 AVI파ì�¼ì�„ ì§€ì •í•œë‹¤.










