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

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

 ------------------------------------------------------------------

 

 WAVE 파일을 재생하기 위해서는 일단 WAVE 파일에 대한 정보를 알아내

야 하는데, 첫번째 강좌에서 설명한 방식대로 각각의 청크 부분 만큼을

떼어내서 읽어내도 되지만, 유령넘이 그렇게 ( 도스 콘솔모드 상태에서

써볼려고.. ) 해봤는데, 결국 십이지장만 꼬이는 결과가 나왔다.안되는

경우도 있는데, 100% 그 방식을 따르지 않는 일부 불량? WAVE파일도 있

거니와 또 다른 방식의 WAVE 도 있고, 구구절절 설명하자면 또 다른 강

좌를 해야 하므로, 일단은 아래와 같은 구조체를 익혀두는 것이 십이지

장이 꼬이지 않는 편안한 삶의 지름길이라 생각하고 유령넘말 믿어보고

한번 살펴보자.

 

------------------------------------------------------------------

 

[ WAVEFORMATEX ]

 

typedef struct {

 

    WORD wFormatTag;       // 웨이브 폼 형식 = WAVE_FORMAT_PCM

    WORD nChannels;        // 채널 수 : 1 = Mono ,  2 = Stereo

    DWORD nSamplesPerSec;  // 샘플링 비율

    DWORD nAvgBytesPerSec; // 초당 Byte 수

    WORD nBlockAlign;      // 블록 정렬

    WORD wBitsPerSample;   // 샘플당 Bit 수 = 8 , 16

    WORD cbSize;           // PCM의 경우는 0

 

} WAVEFORMATEX;          

 

 위의 구조체는 샘플링비율(nSamplesPerSec),샘플크기(wBitsPerSample)

및 모노 스테레오를 지정할 수 있다.  이 구조체에 있는 정보를 가지고

앞으로 WAVE 파일을 마구마구 주물러댈 것 이다. .. -_-a ?? 일단 각각

의 멤버들에 대한설명은 위의 주석만으로도 충분할 것이고.. 실제 사용

법에 대해서 짤막한 소스로 알아보도록 하겠다.

 

------------------------------------------------------------------

 

MMCKINFO mmCkInfoRIFF;

MMCKINFO mmCkInfoChunk;

HMMIO hMMIO;

DWORD waveSize;        //-- Wave Data(순수 WaveData)의 총 길이

WAVEFORMATEX waveFormatEx; //-- WAVEFORMATEX 구조체 선언

 

 

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

//                                                              ||

//-- 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;

    

    // OFN.lpstrFile 에는 지정해둔 디렉토리의 파일위치 경로가

    // 저장되어 있다.  int READ_CHUNK (OPENFILENAME OFN) 함수

    // 헤더에서 보면 OPENFILENAME OFN 으로 파일정보를 전달 받

    // 도록 되어있다. ( FILE_OPEN을 해서 파일위치만 전달해 주

    // 면 되는데, 다른 언어에서는 어떻게 처리하는지 잘 모르겠

    // 다 -_-;; 아무튼 파일의 위치정보만 전달해 주면 된다. 파

    // 일이 있는 디렉토리의 절대경로와 파일 이름(확장자 포함)

    // mmioOpen 함수로 해당위치에서 WAVE 파일을 읽어온다.실패

    // 할 경우에는 FALSE를 리턴해 준다. mmioOpen 의 각 인자는

    // 다음과 같다.

    //

    // HMMIO mmioOpen (

    //  LPSTR szFilename,       

    //  LPMMIOINFO lpmmioinfo,  

    //  DWORD dwOpenFlags       

    // );

 

 

    // RIFF chunk를 찾아간다.

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

    if (mmioDescend(hMMIO, &mmCkInfoRIFF, NULL, MMIO_FINDRIFF)

        != MMSYSERR_NOERROR)

        

        return FALSE;

    

    // format chunk를 찾아간다.

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

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

        MMIO_FINDCHUNK) != MMSYSERR_NOERROR)

        

        return FALSE;

                

    // WAVEFORMATEX 구조체로 부터 포맷정보를 읽어온다.

    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;

    

    // 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;

}

------------------------------------------------------------------

 

 휴.. 정말 머리가 아프다. 아무튼 이제 WAVE 파일에서 앞대가리 쓸모?

없는 부분은 다 읽어냈다. 이 이후에 프로그래밍에서 WAVE 파일에 대한

정보가 필요하면 위에서 설명한  WAVEFORMATEX 구조체를 이용해서 해당

값들을 읽어와서 화면에 뿌려주기만 하면 되는 것이다.

 

[ WAVEFORMATEX ]

 

typedef struct {

 

  WORD wFormatTag;       // 웨이브 폼 형식 = WAVE_FORMAT_PCM

  WORD nChannels;        // 채널 수 : 1 = Mono ,  2 = Stereo

  DWORD nSamplesPerSec;  // 샘플링 비율

  DWORD nAvgBytesPerSec; // 초당 Byte 수

  WORD nBlockAlign;      // 블록 정렬

  WORD wBitsPerSample;   // 샘플당 Bit 수 = 8 , 16

  WORD cbSize;           // PCM의 경우는 0

 

} WAVEFORMATEX;    

 

 예를 들어,현재 WAVE파일이 몇 비트로 샘플링 되어있는지 알고 싶다면

출력지정자 ( WAVEFORMATEX.wBitsPerSample 를 출력하면 된다. ); 나머

지도 같은 방법으로 출력해서 보여줄 수 있다. WAVE 파일 등록정보라고

나오는 메뉴를 구성할 때 쓰기 바란다.

 

------------------------------------------------------------------

 

 두번째 강좌? 끝.. 한꺼번에 너무 많이 하면 하는 사람도 보는 사람도

지례 질려버릴지 모른다는.. 핑계로 막아두고.. ^_^ 놀러가야 겠습니다

던젼시즈도 해야되고.. 룰루.. 일단은 두번째 강좌까지만으로도 WAVE파

일에 대한 정보들은 읽어서 볼수가 있기 때문에, 여러분 스스로 WAVE파

일 등록정보 뷰어 같은 간단한 프로그램 하나씩 만들어 보세요........

 

 다음 세번째 강좌?는 이제 실제로 WAVE파일을 돌려보면서 소리를 들어

봐야 하는데, 첫번째 강좌에서 얘기 했다시피 저수준 오디어 제어를 목

표로 하는 강좌이기 때문에.. 조금 어렵??습니다. 다음 강좌는 링 버퍼

시스템과 WAVEHDR 구조체에 대해서 알아볼텐데,더블버퍼링 기법과 같은

것들은 지금처럼 WAVE 재생 뿐만 아니라, 게임에서의 그래픽 처리 같은

곳에서도 자주 사용하는 기법이므로,잘 봐두시면 오래오래 행복하게 잘

살지도 모릅니다.

 

------------------------------------------------------------------

코멘트쓰기
  좋음   놀람   궁금   화남   슬픔   최고   침묵   시무룩   부끄럼   난감
* 코멘트는 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.