통합검색
· 마을서비스란?  · 포럼마을  · 일반마을  · 테마마을  · 마을랭킹  · 활동왕
· 덱스퍼트란?  · TECBOX   · PRSBOX   · 이용안내  
· DEXT제품군  · 솔루션베이  · S/W & ESD 컴포넌트
· 프로그램베이
· LiveSeminar  · LiveConference
Visual C++ 포럼마을 입니다.
  마을등급 Visual C++   이 마을은 포럼마을 입니다이 마을은 자유가입제 마을 입니다 마을소개 페이지로 이동 전입신청
마을촌장촌장 나성훈 주민 34013 since 2006-12-29
우리마을 공지사항
질문&답변
강좌&팁
자유게시판
자료실
앨범
개인게시판
마을 게시판
등록된 마을 게시판이
없습니다.
랑데브 게시판
칼럼 게시판
개발자 고충상담
Dev Talk
자유토론방
벼룩시장
재나미 우스개
구인/프로젝트 정보
사람인 채용 게시판
  고객지원 게시판
마이 데브피아
 나의 e-Money 내역
 활동왕 My Page
 스크랩한 게시글보기
 쪽지관리
 주소록관리

 강좌&팁
 [API] 저수준 제어를 이용한 WAVE 재생 - 05 [ 끝 ]  | Sound 2002-06-12 오후 1:57:06
 lovesgh  lovesgh님께 메시지 보내기lovesgh님을 내 주소록에 추가합니다.lovesgh님의 개인게시판 가기 번호: 4380  / 읽음:6,182

#include <windows.h>

#include <windowsx.h>

#include <string.h>

#include "resource.h"

 

 

int CNT=0;

 

 

//-- WndProc 및 외부 변수 선언

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

HINSTANCE g_hInst;

TCHAR szAppName[] = TEXT ("WAVE PLAYER II");

 

 

//-- 버퍼의 갯수

const int BufferNum = 6;

 

 

//-- Wave 파일 재생시 Double Buffering 구현을 위한 버퍼

static PBYTE        pBuffer[6] ;

static PWAVEHDR     pWaveHdr[6] ;

 

 

//-- Wave 파일에서 각 버퍼마다 한번에 읽어들일 크기

LONG read_size;

 

 

//-- Wave 처리용 MMIO

MMCKINFO mmCkInfoRIFF;

MMCKINFO mmCkInfoChunk;

HMMIO hMMIO;

DWORD waveSize;

WAVEFORMATEX waveFormatEx;

 

 

//-- 파일 처리(읽기)

OPENFILENAME OFN;

char lpstrFile[MAX_PATH]="";

char FileLocation[100];

 

 

static BOOL bRecording, bReverse, bPaused, bEnding, bPlaying,

            bTerminating ;

 

 

static DWORD dwDataLength ;

static TCHAR szOpenError[] = TEXT ("Error opening waveform audio!");

static TCHAR szMemError [] = TEXT ("Error allocating memory!") ;

static BOOL bMute ;

 

static HWAVEIN  hWaveIn ;

static HWAVEOUT hWaveOut ;

 

LONG mRet;  

 

 

 

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

//                                                                 ||

//-- int READ_CHUNK ( OPENFILENAME OFN )                           ||

//-----------------------------------------------------------------||

//                                                                 ||

//-- OPENFILENAME OFN - OFN.lpstrFile 로 전달 받은 파일의 위치에서 ||

//                      WAVE 파일의 Chunk 헤더를 읽는다            ||

//                                                                 ||

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

int READ_CHUNK ( OPENFILENAME OFN )

{

    // Open the wave file.

    hMMIO = mmioOpen(OFN.lpstrFile, NULL, MMIO_READ | MMIO_ALLOCBUF);

    if (hMMIO == NULL)  

        return FALSE;

    

    // Descend into the RIFF chunk.

    mmCkInfoRIFF.fccType = mmioFOURCC ('W', 'A', 'V', 'E');

    if (mmioDescend(hMMIO, &mmCkInfoRIFF, NULL, MMIO_FINDRIFF) != MMSYSERR_NOERROR)

        return FALSE;

    

    // Descend into the format chunk.

    mmCkInfoChunk.ckid = mmioFOURCC ('f', 'm', 't', ' ');   

    if (mmioDescend(hMMIO, &mmCkInfoChunk, &mmCkInfoRIFF, MMIO_FINDCHUNK)

        != MMSYSERR_NOERROR)

        return FALSE;

                    

    // Read the format information into the WAVEFORMATEX structure.

    if (mmioRead(hMMIO, (char*)&waveFormatEx, sizeof(WAVEFORMATEX)) == -1)

        return FALSE;

    

    // Ascend out of the format chunk.

    if (mmioAscend(hMMIO, &mmCkInfoChunk, 0) != MMSYSERR_NOERROR)

        return FALSE;

    

    // Descend into the data chunk.

    mmCkInfoChunk.ckid = mmioFOURCC ('d', 'a', 't', 'a');

    if (mmioDescend(hMMIO, &mmCkInfoChunk, &mmCkInfoRIFF, MMIO_FINDCHUNK)

        != MMSYSERR_NOERROR)

        return FALSE;

    

    // WAV 데이터의 크기를 저장해둔다.

    waveSize = mmCkInfoChunk.cksize;

 

    return TRUE;

}

 

 

 

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

//                                                                 ||

//-- int MM_WOM_OPEN_FUNCTION ( HWAVEOUT hWaveOut, int BufferNum ) ||

//-----------------------------------------------------------------||

//                                                                 ||

//-- hWaveOut 과 BufferNum을 넘겨 받는다.                          ||

//   - hWaveOut : hWaveOut 핸들                                    ||

//   - BufferNum : 버퍼의 갯수                                     ||

//                                                                 ||

//-- waveOutWrite : 버퍼 재생이 끝나면  MM_WOM_DONE: 메세지를      ||

//                  발생시킨다.                                    ||

//                                                                 ||

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

int MM_WOM_OPEN_FUNCTION ( HWAVEOUT hWaveOut, int BufferNum )

{           

        read_size = ( ( waveFormatEx.nSamplesPerSec * waveFormatEx.nChannels *

            ( waveFormatEx.wBitsPerSample / 8 ) / 10 )  );

 

        if( read_size )

        {

            //MessageBox(hwnd, "MM_WOM_OPEN_FUNCTION ", "Message!", MB_OK);

    

            for( int i=0; i < BufferNum; i++)

            {

                // Allocate memory for wave header

                pWaveHdr[i] = (WAVEHDR *) malloc (sizeof (WAVEHDR)) ;

 

                pBuffer[i]  = (unsigned char *) malloc (read_size);

                

                pWaveHdr[i]->lpData          = (char *) pBuffer[i] ;

                pWaveHdr[i]->dwBufferLength  = read_size ;

                pWaveHdr[i]->dwFlags         = WHDR_DONE;

 

                mmioRead(hMMIO, (char*) pBuffer[i], read_size);

 

                waveOutPrepareHeader (hWaveOut, pWaveHdr[i], sizeof (WAVEHDR)) ;

            }

 

            for( i=0; i < BufferNum; i++)

                waveOutWrite (hWaveOut, pWaveHdr[i], sizeof (WAVEHDR)) ;

            

        }   

        return TRUE ;

}

 

 

    

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

//                                                                 ||

//-- int MM_WOM_DONE_FUNCTION ( HWAVEOUT hWaveOut, int BufferNum ) ||

//-----------------------------------------------------------------||

//                                                                 ||

//                                                                 ||

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

int MM_WOM_DONE_FUNCTION ( HWND hwnd, HWAVEOUT hWaveOut , int BufferNum )

{

    mRet = mmioRead ( hMMIO, ( char* ) pBuffer[CNT], read_size );

 

    if ( ( mRet == -1 )  || ( mRet == 0 ) ) // 1 is Error || 0 is File End

    {

        waveOutClose ( hWaveOut ) ;

        return FALSE;

    }

        

    waveOutWrite ( hWaveOut, pWaveHdr[CNT], sizeof ( WAVEHDR ) ) ;

 

    CNT++;

 

    CNT %= BufferNum ;

 

    bEnding = FALSE ;

    bPlaying = TRUE ;

    

    return TRUE ;

}

 

 

 

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

//                                                                 ||

//-- int MM_WOM_CLOSE_FUNCTION (HWAVEOUT hWaveOut, int BufferNum ) ||

//-----------------------------------------------------------------||

//                                                                 ||

//                                                                 ||

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

int MM_WOM_CLOSE_FUNCTION ( HWAVEOUT hWaveOut,int BufferNum )

{

 

    for ( int i=0; i < BufferNum; i++ )

    {

        waveOutUnprepareHeader ( hWaveOut, pWaveHdr[i], sizeof ( WAVEHDR ) ) ;

        free ( pWaveHdr[i] ) ;

        free ( pBuffer[i] ) ;

    }           

    mmioClose ( hMMIO, 0 ) ;

        

    //MessageBox(hwnd, "MM_WOM_CLOSE_FUNCTION ", "Message!", MB_OK);

 

    bPaused = FALSE ;

    bPlaying = FALSE ;

    bEnding = TRUE ;

                

    /*

    if (bTerminating)

        SendMessage (hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L) ;

    */  

    return TRUE ;

}

 

 

 

 

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

//                                                                 ||

//-- int PLAY_PAUSE ( HWAVEOUT hWaveOut )                          ||

//-----------------------------------------------------------------||

//                                                                 ||

//-- 재생 중 잠시 멈춤 기능                                        ||

//                                                                 ||

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

int PLAY_PAUSE ( HWAVEOUT hWaveOut )

{

 

    // Pause or restart output          

    if ( !bPaused )

    {

        waveOutPause ( hWaveOut ) ;

        bPaused = TRUE ;

    }

    else if ( bPaused )

    {

        waveOutRestart ( hWaveOut ) ;

        bPaused = FALSE ;

        //MessageBox(hwnd, "bPaused = FALSE", "Message", MB_OK );

    }

    

    return TRUE ;

}

 

 

 

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

//                                                                 ||

//-- int PLAY_END ( HWAVEOUT hWaveOut )                            ||

//-----------------------------------------------------------------||

//                                                                 ||

//-- 재생 중지                                                     ||

//                                                                 ||

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

int PLAY_END ( HWAVEOUT hWaveOut )

{

    waveOutReset ( hWaveOut ) ;

    waveOutClose ( hWaveOut ) ;

 

    bEnding = TRUE ;

 

    return TRUE ;

}

 

 

 

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

//                                                                 ||

//  LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM)          ||

//                                                                 ||

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

 

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

{    

    switch(iMessage)

    {

        case WM_COMMAND:

            switch (LOWORD (wParam))

            {

                case IDC_FILEEXIT:

                    PostQuitMessage(0) ;

                    return 0;

        

                case IDC_FILEOPEN:

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

                    OFN.lStructSize = sizeof(OPENFILENAME) ;

                    OFN.hwndOwner=hwnd ;

                    OFN.lpstrFilter="WAV 파일(*.WAV)\0*.WAV\0" ;

                    OFN.lpstrFile=lpstrFile ;

                    OFN.nMaxFile=MAX_PATH ;

 

                    if ( GetOpenFileName(&OFN) != 0 )

                    {       

                        if ( bPlaying )

                        {       

                            waveOutReset (hWaveOut) ;

                            waveOutClose (hWaveOut) ;   

                        }                   

                    }

                    return TRUE ;

 

                case IDC_PLAY_BEG:              

                READ_CHUNK ( OFN ) ;

                    

                    if ( waveOutOpen ( &hWaveOut, WAVE_MAPPER, &waveFormatEx,

                                       (DWORD) hwnd, 0, CALLBACK_WINDOW) )

                    {

                        MessageBeep (MB_ICONEXCLAMATION) ;

                        MessageBox (hwnd, szOpenError, szAppName, MB_ICONEXCLAMATION | MB_OK) ;

                    }                   

                    bPlaying = TRUE ;       

                

                    return TRUE ;

            

                case IDC_PLAY_PAUSE:

                    PLAY_PAUSE ( hWaveOut ) ;   

                    return TRUE ;              

              

                case IDC_PLAY_END:

                    PLAY_END ( hWaveOut ) ;

                    return TRUE ;            

 

            }

            break; //-- InSide : case WM_COMMAND:

 

        case MM_WOM_OPEN:                           

            MM_WOM_OPEN_FUNCTION ( hWaveOut, BufferNum ) ;      

            return TRUE ;           

 

        case MM_WOM_DONE:

            MM_WOM_DONE_FUNCTION ( hwnd, hWaveOut , BufferNum ) ;   

            return TRUE ;           

 

        case MM_WOM_CLOSE:  

            MM_WOM_CLOSE_FUNCTION ( hWaveOut, BufferNum ) ; 

            return TRUE ;

 

        case WM_DESTROY:        

            PostQuitMessage(0);     

            return 0;   

        }

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

}

 

 

 

 

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

//                                                                 ||

//  WinMain()                                                      ||

//                                                                 ||

//|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

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)GetStockObject(WHITE_BRUSH);

    WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);

    WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);

    //WndClass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON13));

    WndClass.hInstance=hInstance;

    WndClass.lpfnWndProc=(WNDPROC)WndProc;

    WndClass.lpszClassName=szAppName;

    WndClass.lpszMenuName=MAKEINTRESOURCE(IDR_MENU1);

    WndClass.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClass(&WndClass);

 

    hwnd=CreateWindow(szAppName,szAppName, //WS_POPUPWINDOW, //

        ,WS_OVERLAPPEDWINDOW,

          0, 0, 306, 250,

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

    ShowWindow(hwnd,nCmdShow);

    

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

        TranslateMessage(&Message);

        DispatchMessage(&Message);

    }

    return Message.wParam;

}

 

위의 파일을 xxxx.cpp 로 저장하신 후 Project에 추가 한 뒤에

 

[MENU]

 

IDC_FILEOPEN

IDC_FILEEXIT

IDC_PLAY_BEG

IDC_PLAY_PAUSE

IDC_PLAY_END

 

Project -> Add to Project -> Files -> xxxx.rc 추가

 

Project -> Settings -> Link -> Object/library modules -> winmm.lib 추가

 

이상의 작업 후 컴파일 하면 됩니다.

VC++ 6.0 에서 테스트 했는데, 이상없이 컴파일/작동 확인 했습니다.

 

 

[코멘트] 좋음
2006-06-23 11:11
 fing5  fing5님께 메시지 보내기fing5님을 내 주소록에 추가합니다.fing5님의 개인게시판 가기 
2002년 6월에 작성하신 강좌... 지금이 2006년 6월이니까 4년이 지난후에 이렇게 보고 글남기고 갑니다..

수고하셨고요. 강좌 정말 많은 도움이 되었습니다.

감사합니다...
저장 취소
[코멘트] 좋음
2009-12-09 14:23
 joon7905  joon7905님께 메시지 보내기joon7905님을 내 주소록에 추가합니다.joon7905님의 개인게시판 가기 
2009년 12월에도 보고 갑니다. 도움 많이 되었습니다. 감사합니다.
저장 취소
코멘트쓰기
  좋음   놀람   궁금   화남   슬픔   최고   침묵   시무룩   부끄럼   난감
* 코멘트는 500자 이내(띄어쓰기 포함)로 적어주세요.
목록 보기   지금 보고 계시는 글을 회원님의 my Mblog >> 스크랩에 넣어두고 다음에 바로 보실 수 있습니다.  
회사소개  |   개인정보취급방침  |  제휴문의  |   광고문의  |   E-Mail 무단수집거부  |   고객지원  |   이용안내  |   세금계산서
사업자등록번호 안내: 220-81-90008 / 통신판매업신고번호 제 2017-서울구로-0055호 / 대표: 홍영준, 서민호
08390, 서울시 구로구 디지털로32길 30, 1211호 / TEL. 02_6719_6200 / FAX. 02-6499-1910
Copyright ⓒ (주) 데브피아. All rights reserved.