이렇게 코드를 짜는 것이 wav 파일을 리소스가 아닌 파일 자체로 읽어서 재생하는 방법 맞나요?

mydream의 이미지

#include <windows.h>
#include "resource.h"
#include <Mmsystem.h>
#pragma comment(lib, "Winmm.lib")
#include <tchar.h>
 
HINSTANCE ghInstance;
HWND ghwnd;
LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpcmdline, int nshowcmd) {
	WNDCLASS wndCls;
	wndCls.cbClsExtra=0;
	wndCls.cbWndExtra=0;
	wndCls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	wndCls.hCursor=LoadCursor(NULL, IDC_ARROW);
	wndCls.hIcon=NULL;
	wndCls.hInstance=ghInstance=hInstance;
	wndCls.lpfnWndProc=WinProc;
	wndCls.lpszClassName=TEXT("wavesound");
	wndCls.lpszMenuName=NULL;
	wndCls.style=CS_HREDRAW | CS_VREDRAW;
	RegisterClass(&wndCls);
	HWND hwnd=ghwnd=CreateWindow(wndCls.lpszClassName, TEXT("wavesound test"), WS_OVERLAPPEDWINDOW, 300, 300, 500, 500, NULL, NULL, hInstance, NULL);
	ShowWindow(hwnd, nshowcmd);
	MSG message;
	while(  GetMessage(&message, NULL, 0, 0) ) {
		TranslateMessage(&message);
		DispatchMessage(&message);
	}
	return message.wParam;
}
 
void CALLBACK waveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
 
}
TCHAR tmbuffer[1024];
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
	switch(message) {
		case WM_CREATE:
			{
				/*LPTSTR lpRes;
				HANDLE hResInfo, hRes;
				hResInfo=FindResource(ghInstance, MAKEINTRESOURCE(IDR_WAVE1) , TEXT("WAVE"));
				//hResInfo=FindResource(ghInstance, TEXT("notify.wav") , TEXT("WAVE"));				
				if(hResInfo==NULL) {
					MessageBox(hwnd, TEXT("WM_CREATE"), NULL, MB_OK);
					return 0;
				}
 
				hRes=LoadResource(ghInstance, (HRSRC)hResInfo);
				if(hRes==NULL) {  return 0;  }
				lpRes=(LPTSTR)LockResource(hRes);
				if(lpRes==NULL) {  
					FreeResource(hRes);
					return 0;
				}
				sndPlaySound(lpRes, SND_MEMORY | SND_SYNC | SND_NODEFAULT);
				UnlockResource(hRes);
				FreeResource(hRes);*/
 
				HMMIO mhandle=mmioOpen(  TEXT("notify.wav"), NULL, MMIO_READ  );
				if(mhandle==NULL) {	return 0;	}
				MMIOINFO mediaInfo;
				CHAR buffer[1024];
				if(  mmioSetBuffer(mhandle, buffer, 1024, 0)!=0  ) {
					MessageBox(  ghwnd, TEXT("mmioSetBuffer failed."), NULL, MB_OK);
					mmioClose(mhandle, MMIO_FHOPEN);
					return FALSE;
				}
				MessageBox(ghwnd, TEXT("DS_OK"), NULL, MB_OK);
				MMRESULT mresult=mmioGetInfo(mhandle, &mediaInfo, 0);
				if(mresult!=0) {
					mmioClose(mhandle, MMIO_FHOPEN);
					return FALSE;
				}
 
				LONG rbytes=mmioRead(mhandle, mediaInfo.pchBuffer, 1024);
				if(rbytes==0 || rbytes==-1) {
					MessageBox(ghwnd, TEXT("mmioRead can't read bytes."), NULL, MB_OK);
				}
 
				//_stprintf(  tmbuffer, TEXT("%d"), rbytes);//test
				//MessageBox(ghwnd, tmbuffer, NULL, MB_OK);//test
 
 
 
 
				HWAVEOUT ad_handle;
				UINT ad_id=waveOutGetNumDevs();
				WAVEFORMATEX wfx;
				DWORD_PTR callback_data=0;
 
				_stprintf(  tmbuffer, TEXT("%ld"), ad_id);
				MessageBox(hwnd, tmbuffer, NULL, MB_OK);
 
 
				MMRESULT wResult=waveOutOpen(&ad_handle, ad_id, &wfx, (DWORD_PTR)waveOutProc, callback_data, CALLBACK_FUNCTION);
				//MMRESULT wResult=waveOutOpen(&ad_handle, WAVE_MAPPER, &wfx, (DWORD_PTR)waveOutProc, callback_data, CALLBACK_FUNCTION);
 
				if(wResult!=MMSYSERR_NOERROR) {
					MessageBox(ghwnd, TEXT("waveOutOpen failed."), NULL, MB_OK);
				}
				MessageBox(ghwnd, TEXT("to here"), NULL, MB_OK);//test
				WAVEHDR whdr;
				whdr.lpData=mediaInfo.pchBuffer;
				whdr.dwBufferLength=mediaInfo.cchBuffer;
				whdr.dwFlags=0L;
				whdr.dwLoops=0L;
				wResult=waveOutPrepareHeader(ad_handle, &whdr, sizeof(whdr));
 
				if(wResult!=MMSYSERR_NOERROR) {
					MessageBox(ghwnd, TEXT("waveOutPrepareHeader failed."), NULL, MB_OK);
				}
 
				wResult=waveOutWrite(ad_handle, &whdr, sizeof(whdr));
				if(wResult!=MMSYSERR_NOERROR) {
					MessageBox(ghwnd, TEXT("waveOutWrite failed."), NULL, MB_OK);
				}
 
				return 0;
			}
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
	}
	return DefWindowProc(hwnd, message, wparam, lparam);
}

wav 파일을 리소스로 읽어 재생할 때는 PlaySound나 SndPlaySound를 사용하는 것으로 알고 있습니다. 리소스가 아닌 파일 자체를 재생하기 위해 위와 같이 코드를 짰고 마지막으로 버퍼의 읽어들인 내용을 장치로 출력해서 소리를 들어보려고 WaveOutWrite 함수를 호출했는데 재생이 안됩니다. WaveOutOpen에서부터 죽 아래로 언급한 Wave류 함수들이 실패하고 맙니다. 어디가 틀렸으며 뭘 추가해야 파일이 재생될지 알 수 있을까요?

shint의 이미지

여러가지 정보가 보이네요.

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

mydream의 이미지

WaveOutOpen의 첫 번째 매개변수에서 HWAVEOUT 데이터를 회수해와야 하는데 제대로 회수를 못하네요. 저 변수에 NULL을 대입하고 NULL인지 아닌지를 확인해보니 그냥 NULL로 나옵니다. 회수가 안되는 원인이 뭔지 알려주실 수 있나요?

shint의 이미지

- 일단. 소스를 백업하고. 필요한 내용만 사용해서 테스트 해봅니다. 잘 모를경우. 예제를 따라해봅니다.

- 각 함수를 MSDN에서 인자값. 리턴값. 오류값을 확인해봅니다.
리턴값으로 오류에 대한 정보를 확인해보실 수 있습니다.

- 오류가 확인 되었다면. 해결 하거나. 해결이 어렵다면.
- 오디오. 게임. Win32API. MFC. VC++ 프로그래밍 책과 예제소스를 따라해 봅니다.
네이버 책에서 검색해보고. 도서관 서점에서 확인해보실 수 있습니다.
- 코드 프로젝트. 네이버. 구글에서 예제소스를 참고해보실 수 있습니다.

잘 된거 따라해보시기 바랍니다. 저도 잘 몰라요. ㅇ_ㅇ;; 제가 만든것도 있지만. 엉터리라서... 책보시는것이 좋습니다.

waveOutOpen 함수 WINAPI
http://blog.naver.com/windslime?Redirect=Log&logNo=80042297098

Return Values

함수가 성공하면 MMSYSERR_NOERROR가 반환되며
실패하면 다른 값들이 반환된다. 그 값들은 아래와 같다.

MMSYSERR_ALLOCATED : 지정된 리소스는 이미 할당되어 있다.
MMSYSERR_BADDEVICEID : 지정된 장치 식별자가 잘못 되었다.
MMSYSERR_NODRIVER : 장치 드라이버가 존재하지 않는다.
MMSYSERR_NOMEM : 할당할 수 없거나 메모리 공간이 부족하다.
WAVERR_BADFORMAT : 지원하지 않는 웨이브 오디오 포맷을 열려고 시도한다.
WAVERR_SYNC : WAVE_ALLOWSYNC 플래그의 지정 없이
동기식 장치를 열기위해 waveOutOpen 함수를 호출했다.

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

optimistichacker의 이미지

리소스 버전 코드에서 sndPlaySound API 함수 첫번째 인자로 전달하는 메모리만

파일의 내용을 읽은 배열로 전달해 주면 되는 걸요.

직접 waveOutWrite API 함수로 Waveform 데이터를 넘겨주는 건 하시려는 거에 비해서 노가다급이라고 보여집니다.

저걸 직접 쓰는 경우는 스트리밍 외엔 없어요.

익명 사용자의 이미지

sndPlaySound 함수는 메모리 안의 이미지를 전달받는다고 나와있던데요. 그 이미지를 얻기 위해 LockResource로 반환된 값을 전달하는 것으로 알고 있습니다. 또 LockResource 함수는 HANDLE을 전달받고요, FindSource 함수도 HANDLE를 전달받고요. 즉 리소스에 대한 HANDLE이 있어야 sndPlaySound를 최종적으로 사용해서 재생할 수 있다는 이야기인데, 읽어들인 파일의 내용은 리소스도 핸들도, 이미지도 아니기 때문에 파일의 내용을 핸들이나 리소스로 변환하는 뭔가가 필요할 것 같은데. 그런 것 없나요? 파일의 내용은 mmioRead 함수로 읽기는 했습니다만. 그렇다면 저 읽어들인 내용을 어떻게 sndPlaySound에 사용하는가가 문제인데요?

shint의 이미지

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.