VC录音机程序开发过程

    技术2024-06-30  63

    (1)常见的数据类型与数据结构:

            HWAVEIN     m_hwavin;         //输入设备句柄,在录音时要用

     

            HWAVEOUT  m_hwavout;        // 输出设备句柄,在回放时要用

                  

           WAVEFORMATEX  m_waveform;  //设置采集的声音格式     

         

           WAVEHDR   m_wavehdr;        //音频数据块缓存结构

     

       音频数据块缓存结构WAVEHDR   其声明如下:     type struct{   LPSTR lpData;                 //指向锁定的数据缓冲区的指针   DWORD dwBufferLength;         //数据缓冲区的大小   DWORD dwByteRecorded;         //录音时指明缓冲区中的数据量,

                                                   When the header is used in input, this member specifies how much data is in the buffer.   DWORD dwUser;                 //用户数据   DWORD dwFlag;                 //提供缓冲区信息的标志   DWORD dwLoops;                 //循环播放的次数   struct wavehdr_tag *lpNext; //保留   DWORD reserved;                 //保留   } WAVEHDR;

    这个结构体的应用:

             首先申请一段内存:   char m_cbBuffer1[INP_BUFFER_SIZE]; //声音临时缓存1

     

     

                m_wavehdr.lpData=(LPTSTR)m_cbBuffer1;

                m_wavehdr.dwBufferLength=INP_BUFFER_SIZE;

                m_wavehdr.dwBytesRecorded = 0;             m_wavehdr.dwUser=0;             m_wavehdr.dwFlags=0;             m_wavehdr.dwLoops=1;             m_wavehdr.lpNext=NULL;             m_wavehdr.reserved=0 ;

    //设置缓冲区

    waveInPrepareHeader(&m_hwavin,&m_wavehdr,sizeof(WAVEHDR));

    waveInAddBuffer(&m_hwavin,&m_wavehdr,sizeof(WAVEHDR));

     

    //开始录音

     

    waveStart(&m_hwavin);

     

    (2) 处理几个消息的函数

         第一:MM_WOM_CLOSE消息处理函数        //LRESULT通常是用来作为消息处理函数的返回值的

                  

    LRESULT CWaveRecordDlg::OnMM_WIM_CLOSE(UINT wParam, LONG lParam) { waveInUnprepareHeader(m_hWaveIn, &m_WAVEHDR1, sizeof (WAVEHDR)) ; waveInUnprepareHeader(m_hWaveIn, &m_WAVEHDR2, sizeof (WAVEHDR)) ; return NULL; }

     

     

     

      DWORD m_dwDataLength;   //数据长度   PBYTE m_pSaveBuffer;         //音频存储内存

     

       第二:MM_WIM_DATA消息处理函数

    LRESULT CWaveRecordDlg::OnMM_WIM_DATA(UINT wParam, LONG lParam) {     PWAVEHDR pWaveHdr = (PWAVEHDR)lParam;

        if(pWaveHdr->dwBytesRecorded > 0){      m_pSaveBuffer = (PBYTE)realloc(m_pSaveBuffer,m_dwDataLength + pWaveHdr->dwBytesRecorded);

        if(m_pSaveBuffer == NULL){     waveInClose (m_hWaveIn);     MessageBeep (MB_ICONEXCLAMATION) ;     AfxMessageBox("erro memory");     return NULL;    }

     

       memcpy(m_pSaveBuffer+m_dwDataLength , pWaveHdr->lpData,pWaveHdr->dwBytesRecorded);

       m_dwDataLength += pWaveHdr->dwBytesRecorded;  }

     

     

      if(m_nRecordState == RECORD_STATE_STOPING){    waveInClose(m_hWaveIn);    }

     

     

      waveInAddBuffer(m_hWaveIn, pWaveHdr, sizeof (WAVEHDR));

     

    //The waveInAddBuffer function sends an input buffer to the given waveform-audio input device. When the buffer is filled, the application is notified.

     

    return NULL;

    }

     

    (3) wav  文件的回放

        

     if(waveOutOpen(&m_hWaveOut,WAVE_MAPPER,&m_waveform,(DWORD)m_hWnd, NULL, CALLBACK_WINDOW))

       

        {        MessageBeep(MB_ICONEXCLAMATION);        MessageBox(_T("录制声音失败!"),_T("错误"),MB_ICONEXCLAMATION|MB_OK);        return;       }

     

     

     

     LRESULT CWaveRecordDlg::OnMM_WON_OPEN(UINT wParam,LONG lParam){    memset(&m_WAVEHDR1,0,sizeof(WAVEHDR));    m_WAVEHDR1.lpData = (char *)m_pSaveBuffer;                               //指向要播放的内存    m_WAVEHDR1.dwBufferLength = m_dwDataLength;                        //播放的长度    m_WAVEHDR1.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;     m_WAVEHDR1.dwLoops = 1;

     

     

        waveOutPrepareHeader(m_hWaveOut,&m_WAVEHDR1,sizeof(WAVEHDR));

        waveOutWrite(m_hWaveOut,&m_WAVEHDR1,sizeof(WAVEHDR));

     

     

        m_nRecordState = RECORD_STATE_PLAYING;    SetButtonState();    return NULL;}

     

     

    LRESULT CWaveRecordDlg::OnMM_WOM_DONE(UINT wParam,LONG lParam){    PWAVEHDR pWaveHdr = (PWAVEHDR)lParam;

        waveOutUnprepareHeader (m_hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;    waveOutClose (m_hWaveOut);

        return NULL;}

     

    LRESULT CWaveRecordDlg::OnMM_WOM_CLOSE(UINT wParam,LONG lParam){    m_nRecordState = RECORD_STATE_STOP;    SetButtonState();    return NULL;}

     

     

    (4)wav文件格式

    表 .WAV档案格式

    偏移量 位元组 资料00004「RIFF」00044波形块的大小(档案大小减8)00084「WAVE」000C4「fmt 」00104格式块的大小(16位元组)00142wf.wFormatTag = WAVE_FORMAT_PCM = 100162wf.nChannels00184wf.nSamplesPerSec001C4wf.nAvgBytesPerSec00202wf.nBlockAlign00222wf.wBitsPerSample00244「data」00284波形资料的大小002C 波形资料

     

     

    (5)wav文件的保存

        第一:读wav头文件信息

     

     #define WAVE_HEADER_SIZE 44

    int CWaveRecordDlg::read_wav_head(WAVEFORMATEX *wf,char **out_buffer,int *out_len,char *in_buffer,int in_len){    char *lp_pos;    int itmp;        lp_pos = in_buffer;    if(in_buffer == NULL || in_len == 0 || in_len < WAVE_HEADER_SIZE || wf==NULL)        return 1;

        if(strncmp(lp_pos,"RIFF",4)!=0)        return -1;    lp_pos += 4;

        itmp = *((int*)lp_pos);    if(itmp != (in_len-8))        return -1;    lp_pos += 4;

        if(strncmp(lp_pos,"WAVEfmt ",8)!=0)        return -1;    lp_pos += 8;

        itmp = *((int*)lp_pos);    if(itmp != 16)        return -1;    lp_pos += 4;

     

        /**//*格式信息*/    memcpy(wf,lp_pos,16);    lp_pos += 16;

        if(strncmp(lp_pos,"data",4)!=0)        return -1;    lp_pos += 4;

     

     

        //真正的数据长度    *out_len = *((int*)lp_pos);    lp_pos += 4;

        if(*out_len != (in_len - WAVE_HEADER_SIZE))        return 1;

        *out_buffer = (char*)malloc(*out_len);    if(*out_buffer == NULL)        return -2;

        memcpy(*out_buffer,lp_pos,*out_len);            return 0;}

     

    第二:写wav头文件函数

    int CWaveRecordDlg::write_wav_head(WAVEFORMATEX *wf,char *in_buffer,int in_len,char **out_buffer, int *out_len){

        char *buffer;    int *int_tmp,pos=0;

        *out_len = WAVE_HEADER_SIZE + in_len;    buffer = (char*)malloc(*out_len);    if(buffer == NULL)         return -1;    memcpy(buffer,"RIFF",4);    pos = 4;

     

     

        int_tmp = (int*)(buffer+pos);    *int_tmp = WAVE_HEADER_SIZE + in_len - 8;/**//*波形块的大小(档案大小减8)*/    pos += 4;

        memcpy(buffer+pos,"WAVEfmt ",8);    pos += 8;

        int_tmp = (int*)(buffer+pos);    *int_tmp = 16;    pos += 4;

     

        /**//*格式信息*/    memcpy(buffer+pos,wf,16);    pos += 16;

        memcpy(buffer+pos,"data",4);    pos += 4;

        int_tmp = (int*)(buffer+pos);    *int_tmp = in_len;    pos += 4;

        memcpy(buffer+pos,in_buffer,in_len);

        *out_buffer = buffer;

        return 0;}

     

     

     

     

     

              

    最新回复(0)