Windows环境下的麦克风录音系统(7)

类别:VC语言 点击:0 评论:0 推荐:

我们有了这两个强有力的类的支持就可以开始我们的编程工作了….

   1.用VC6++建立一个MFC基于对话框的工程:MicDemo;

   2.添加我们的两个类CSoundIn,CwaveFile;       

   3.当我们点击开始(Start)按钮的时候我们就要开始录音了…

 

         void CMicDemoDlg::OnStart()

        {

                m_btnStart.EnableWindow(FALSE);               

                if(theSoundCapture().__initMic())

                {

                      m_filePath.SetWindowText(_T("yangchen.wav."));        

                      theSoundCapture().__createOutputWaveFile(_T("yangchen.wav"));                    

                     if(!theSoundCapture().__openMic())

                      {

                        ::MessageBox(this->m_hWnd,_T("Can not open microphone!"), _T("Error"),MB_OK|MB_ICONERROR);

                         return;

                      }

                }

               

                m_btnStop.EnableWindow(TRUE);

             

              // 设置定时器是为了画波形用的     

                SetTimer(1, 200 /*start slow*/, NULL);

           }

 

    4.在定时器的回调函数中画波形.

           void CMicDemoDlg::OnTimer(UINT nIDEvent)

            {

                    if(nIDEvent == 1)

                   {          

                                static const int xCon = 13;

                                static const int yCon = 13;

                                static const int wCon = 623;

                                static const int hCon = 80;

                               

                                CClientDC dc(this);

                               

                                CBitmap   Bitmap;

                                CBitmap * pbmOld = NULL;                             

                                CDC         dcMem;

                               

                                dcMem.CreateCompatibleDC(&dc);                

                                Bitmap.CreateCompatibleBitmap(&dc,wCon,hCon);

                               

                                pbmOld = dcMem.SelectObject(&Bitmap);

                               

                                dcMem.PatBlt(0,0,wCon,hCon, WHITENESS);                             

                                dcMem.MoveTo(0,hCon/2);

                               

                                //

                                // display incomming signal--key idea!

                                //

                                for(int x =0 ; x < wCon; x++)  // display Input

                                {

                                          dcMem.LineTo(x,(hCon >> 1) - (theSoundCapture().InputBuffer[x] >> 7));

                                }

                               

                                dc.BitBlt(xCon,yCon,wCon,hCon,&dcMem, 0, 0, SRCCOPY);

                               

                                dcMem.SelectObject(pbmOld);

                                dcMem.DeleteDC();            

                  }

                  else

                         CDialog::OnTimer(nIDEvent);

            }

      

      5.点击停止(Stop)按钮的时候停止录音和写WAV文件

                  void CMicDemoDlg::OnStop()

                 {

                        m_btnStop.EnableWindow(FALSE); 

                        theSoundCapture().__closeMic(); 

                        m_btnStart.EnableWindow(TRUE);

                 }

看完整段代码你可能会很奇怪怎么在CmicDemoDlg中居然都没有定义一个CSoundIn对象??呵呵,原因很简单,因为设备的独占性所以在一个时刻只能有一个CSoundIn对象存在(因为CSoundIn对象需要占据录音设备),所以我们必须限制程序员生成CSoundIn对象的数量,怎么限制呢?那就是把CSoundIn的构造函数放在private区域里面:

  

     private:

                BOOL  GetBestWaveFormat(WAVEFORMATEX & waveFormatEx);

               

                // because sound card is one and only so i must limit the number of CSoundIn object,

                // but how to limit the class object nums?maybe put constructor into private scope is

                // a good idea,:-)

        CSoundIn();         

 

这样的话就根本无法声明一个CSoundIn对象,不信你试一下在你的代码中写上:

     CSoundIn  soundInObj;

 能编译通过吗?肯定是不能,那如何调用CSoundIn的成员函数呢?答案是通过一个全局函数:

 

              // global function,:-(

              // client can only through this function to use CSoundIn object

              CSoundIn & theSoundCapture()

              {

                     static CSoundIn p;

                     return p;

               }

 

  这时候你应该明白了为什么上面的代码中调用CSoundIn的成员函数的时候都是用theSoundCapture来做的原因了吧. 

本文地址:http://com.8s8s.com/it/it1205.htm