C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[42462] Re:pcm 파일로 저장 하는 법
마술감자 [magicpotato] 1572 읽음    2005-11-14 13:42
전 잘 모르겠지만 도움이 될까 하고 링크를 알려 드립니다.


http://thecoadletter.com/article/0,1410,28332,00.html


혹시 사라질지 모르니 긁은 내용


Quick and Easy Audio Recording in C++ Builder
Rating:      Ratings: 9     Rate it


Abstract: Use the MCIWnd* family of functions to implement something lacking in TMediaPlayer - easily configurable audio recording.

Quick and Easy Audio Recording in C++ Builder
Although the TMediaPlayer component in Builder does just about everything I could want, one problem I've encountered with it is in recording. This article details how to provide recording support in Builder with the MCI Window interface.

Simple Recording?

The problem is fairly simple in TMediaPlayer - you need to have a valid FileName entry before calling Open(), which means the audio has to exist before you record it! As well it is that is it quite awkward to change audio settings, or create brand-new audio, since there are no VCL calls for this kind of access. While none of this is insurmountable, for my recording needs all I wanted was a simple solution, ideally with just two buttons: Record and Stop.

Surveying the Window literature gave me the idea to use the MCIWnd* class of functions, and the result was a very simple solution. The MCI Window wraps all the general media calls in a window you create on your form. Although it can be used for more than recording, there's little need with TMediaPlayer available, so we'll just focus on that aspect here.

The sample code shows how to set up a window, record audio, and close. The program is exceedingly simple, and so makes it straightforward for you to cut and paste recording functionality into your own programs. Discussing the code will show just how easy it is to set up and record.

Coding Our Window

First off, we add code to create an MCI Window and close it. Since the window can exist for the life of the program, we handle construction and destruction in the form's constructor and destructor:
  extern HINSTANCE g_hInstance;
  HANDLE m_hMCIWnd =NULL;
  //----------------------------------------------------------------
  __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
  {
    m_hMCIWnd=MCIWndCreate(Handle,
                           g_hInstance,
                           WS_CHILD | WS_OVERLAPPED,
                           NULL );
    if ( NULL==m_hMCIWnd ) // error?
    {
      MessageBox(Handle,"Error Creating MCIWnd Window!",NULL, MB_OK);
      return;
    }
  }
  //-----------------------------------------------------------------
  __fastcall TForm1::~TForm1(void)
  {
    MCIWndDestroy(m_hMCIWnd);
  }

All of the parameters to MCIWndCreate() are straightforward, with the exception of g_hInstance, which is the program's HINSTANCE value from our WinMain (Project1.cpp). The actual program source code has more options than shown here, since you can choose to show this window and display buttons, framing, and so forth. However, since all we want is recording, we've opted to leave off the WS_VISIBLE flag.

This window is like any other window in the system. You can communicate with it via SendMessage() and PostMessage(), but fortunately there are macros that wrap these calls into simpler formats, the MCIWnd* functions. As a first example we have the commands to set up and begin recording a new file, placed in our Record button handler:


  void __fastcall TForm1::Button1Click(TObject *Sender)
  {
    // create new .WAV file
    MCIWndNew(m_hMCIWnd, "waveaudio");
    // begin recording
    MCIWndRecord(m_hMCIWnd);
  }



Stopping is equally easy, by responding to the Stop button, thereby making audio recording possible in five lines of code (after setup of course):


  void __fastcall TForm1::Button2Click(TObject *Sender)
  {
    // stop recording and save file
    MCIWndStop(m_hMCIWnd);
    MCIWndSave(m_hMCIWnd,file);
    MCIWndClose(m_hMCIWnd);
  }



As always, there are some caveats. Since the filename is not needed until closing, you rightly can guess that the file is maintained in memory, and so this isn't a solution for recording large audio files. As well, there is no provision for monitoring of buffers or mixing - if you need that kind of low-level control, consider writing your own buffer recording routines. An excellent reference for that is 'Programming Windows' by Charles Petzold.

Changing Settings

We now need to look at altering settings for frequency, channels and the like. Recording defaults to 11 kilohertz, 8 bit sampling, and single channel (mono); if this is what you need, no further adjustments are necessary. However, settings can be changed with one call (which in the program is placed between MCIWndNew() and MCIWndRecord()):


  MCI_WAVE_SET_PARMS set_parms; // audio parameters
  set_parms.wFormatTag      = WAVE_FORMAT_PCM;
  set_parms.wBitsPerSample  = 16;
  set_parms.nChannels       = 1;
  set_parms.nSamplesPerSec  = 44100;
  set_parms.nBlockAlign     = (set_parms.nChannels*set_parms.wBitsPerSample)/8;
  set_parms.nAvgBytesPerSec = ((set_parms.wBitsPerSample) *
                                set_parms.nChannels *
                                set_parms.nSamplesPerSec)/8;
  // now send the format changes with MCI_SET
  int deviceID=MCIWndGetDeviceID(m_hMCIWnd);
  int result = mciSendCommand( deviceID, MCI_SET,
                               MCI_WAIT
                             | MCI_WAVE_SET_FORMATTAG
                             | MCI_WAVE_SET_BITSPERSAMPLE
                             | MCI_WAVE_SET_CHANNELS
                             | MCI_WAVE_SET_SAMPLESPERSEC
                             | MCI_WAVE_SET_AVGBYTESPERSEC
                             | MCI_WAVE_SET_BLOCKALIGN,
                               (DWORD)(LPVOID)&set_parms);
  if ( result ) // failed?
  {
    char buffer[100];
    mciGetErrorString(result, buffer, sizeof(buffer));
    MessageBox( NULL, buffer, "MCI_WAVE_SET_1", MB_OK);
    return;
  }


Because there is no MCIWnd* call for setting the audio, we fall back on the mciSendCommand(), which needs a device ID (provided by MCIWndGetDeviceID), a structure containing the parameters, and flags indicating which structure items are to be changed.

The structure values you most likely will change are wBitsPerSample (8 or 16), nChannels (1 for mono, 2 for stereo), and nSamplesPerSec (frequency in hertz). While you can change the other parameters, there might be problems, since not all values work. For instance if you change the wFormatTag value to WAVE_FORMAT_ADPCM you'll get the response 'The parameter is out of range for the specified command'. The morale is to stick to known values, or be prepared to test a lot.

In conclusion, be sure to look up the Builder documentation on the MCWnd* calls. Although TMediaPlayer satisfies most needs, using MCI window calls can give you easy and flexible recording in Builder.


Shop Borland    Downloads 

NOTE: The views and information expressed in this document represent those of its author(s) who are solely responsible for its content. Borland does not make or give any representation or warranty with respect to such content.



Votes   1 0 1 2 5     Responses: 9
Average: 4.11111

1=Poor, 5=Excellent   1 2 3 4 5
    

Add or View comments 
 
            
Rating   1 2 3 4 5    




 


Borland® Copyright© 1994 - 2005 Borland Software Corporation. All rights reserved
Report Piracy | Legal Notices | Privacy Policy

+ -

관련 글 리스트
42453 pcm 파일로 저장 하는 법 이성제 1578 2005/11/13
42462     Re:pcm 파일로 저장 하는 법 마술감자 1572 2005/11/14
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.