基于wince的录音机

68 篇文章 2 订阅
31 篇文章 1 订阅

基于wince的录音机



基于D:\WINCE500\PUBLIC\COMMON\SDK\SAMPLES\AUDIO\WAVREC 的录音程序

建立: PCRecord MFC 工程

工程加入:

wavrec.cpp

wavefile.cpp

wavefile.h

将wavrec.cpp 的 winmain 函数声明去掉,把 winmain(){} 的{}改为void StartRecord(char *pFile);

函数(为了避免一开始就执行录音窗口)

PCRecordDlg.cpp 加入

#include "wavefile.h"

#include "wavrec.h" //wavrec.h 加入void StartRecord(char *pFile);

1. 加入 edit 组件名为IDC_SAVE_FILE,加入按钮IDC_BROWSE,并加入按钮事件

         CFileDialog    Dlg(false);

     if (Dlg.DoModal() == IDCANCEL)

         return;

     m_strFile = Dlg.GetPathName();

     m_strFile+= ".wav";

     //MessageBox(m_strFile,TEXT("msg"),MB_OK);

     UpdateData(false);

2.      DoDataExchange 在这里加入DDX_Text(pDX, IDC_SAVE_FILE, m_strFile); 数据更新,这就实现了路径的显示

3.      加入按钮OnStart,事件为:

void CPCRecordDlg::OnBnClickedOnstart()

{ //MessageBox(NULL,(LPCTSTR)pFile,TEXT("msg"),MB_OK);

         if (m_strFile.IsEmpty())

         {

         AfxMessageBox(_T("请先输入要保存的文件名"));

         return;

         }

UpdateData(true);

StartRecord((char *)m_strFile.GetBuffer(m_strFile.GetLength()));

}

4.      将PTSTR pszFilename = (PTSTR)pFile; 估计 TEXT 是PTSTR型

5.       到此是可以正常玩一个录音的了,但是,只能有一个主线程在转啊,所以一旦运行录音整个dialog就停止了,只能等到录音完,所以必须创建一个进程来跑这个函数!看下面在类中创建线程
void CPCRecordDlg::OnBnClickedOnstart()
{
   if (m_strFile.IsEmpty())
   {
   AfxMessageBox(_T("请先输入要保存的文件名"));
   return; 
   }
   //pFile=m_strFile.GetBuffer(m_strFile.GetLength());
   //MessageBox(pFile,TEXT("msg"),MB_OK);

UpdateData(true);
SetTimer(1, 10, NULL);
//

DWORD   dwThreadID;   
HANDLE hThread = CreateThread(NULL, //   no   security   attributes     
0, //   use   default   stack   size     
(LPTHREAD_START_ROUTINE)ThreadFunc,     
(LPVOID)NULL, //   可以通过这个参数传送一个参数的指针到处理函数中   
0, //   creation   flag     
&dwThreadID); //   thread   identifier     
if (hThread   ==   NULL)     
MessageBox(TEXT("创建线程出错!"),TEXT("msg"),MB_OK);;   
StartRe=(char *)m_strFile.GetBuffer(m_strFile.GetLength());

}
DWORD   ThreadFunc(LPVOID lpVoid) //lpVoid即为创建线程时传入的参数,可以为空   
{     
//在你的线程中的处理。 
   //MessageBox(NULL,TEXT("msg"),TEXT("msg"),MB_OK);
      StartRecord(StartRe);
return   0;   
}


6. 在空白处加上线程处理函数

DWORD   ThreadFunc(LPVOID lpVoid) //lpVoid即为创建线程时传入的参数,可以为空

{    

//在你的线程中的处理。

       //MessageBox(NULL,TEXT("msg"),TEXT("msg"),MB_OK);

      StartRecord(StartRe);

return   0;  

}

7.       在头文件中加入

static DWORD WINAPI ThreadFunc(LPVOID lpVoid);

static char *StartRe;



又加左两天时间下去,修修补补,总算有个样了,我不想再放时间去这个东西了,还有其它任务,就这样交差了吧!
先上张PIC


随时可以停,但不能边录边写文件,因为我还没研究到这一步,呵呵

下面代码部分:
工程要加入wince里面的 
wavefile.cpp
wavefile.h

waveInOpen(&hwi,WAVE_MAPPER, pwfx, (DWORD)this->m_hWnd, NULL, CALLBACK_WINDOW);//CALLBACK_WINDOW 被这个搞惨,如果是CALLBACK_EVENT 那些
    ON_THREAD_MESSAGE(MM_WIM_OPEN,OnMM_WIM_OPEN)
    ON_THREAD_MESSAGE(MM_WIM_DATA,OnMM_WIM_DATA)
    ON_THREAD_MESSAGE(MM_WIM_CLOSE,OnMM_WIM_CLOSE)
就不会响应!
中途还改用线程,也不好操作!

//  WinceRecordDlg.cpp : implementation file
//

#include "stdafx.h"
#include "WinceRecord.h"
#include "WinceRecordDlg.h"
#include "wavefile.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define MRCHECK(mr,str)\
    if ((mr != MMSYSERR_NOERROR)) { RETAILMSG(1, (TEXT(#str) TEXT(" failed. mr=%08x\r\n"), mr)); goto ERROR_DONE;}
/
// CWinceRecordDlg dialog

CWinceRecordDlg::CWinceRecordDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CWinceRecordDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CWinceRecordDlg)
        // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CWinceRecordDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CWinceRecordDlg)
        // NOTE: the ClassWizard will add DDX and DDV calls here
    DDX_Text(pDX, IDC_SAVE_FILE, m_strFile);
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CWinceRecordDlg, CDialog)
    //{{AFX_MSG_MAP(CWinceRecordDlg)
    ON_THREAD_MESSAGE(MM_WIM_OPEN,OnMM_WIM_OPEN)
    ON_THREAD_MESSAGE(MM_WIM_DATA,OnMM_WIM_DATA)
    ON_THREAD_MESSAGE(MM_WIM_CLOSE,OnMM_WIM_CLOSE)
    ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
    ON_BN_CLICKED(IDC_REC_START, OnRecStart)
    ON_BN_CLICKED(IDC_REC_STOP, OnRecStop)
    ON_BN_CLICKED(IDC_PLAY, OnPlay)
    ON_BN_CLICKED(IDC_STOP, OnStop)
    ON_BN_CLICKED(IDC_PAUSE, OnPause)
    ON_BN_CLICKED(IDC_CONTINUE, OnContinue)
    ON_WM_TIMER()
    ON_BN_CLICKED(IDC_REC_HOLD, OnRecHold)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_BN_CLICKED(IDC_REC_CON, OnRecCon)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CWinceRecordDlg message handlers

BOOL CWinceRecordDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Set the icon for this dialog. The framework does this automatically
    // when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    
    CenterWindow(GetDesktopWindow());    // center to the hpc screen

    // TODO: Add extra initialization here

saved=false;
GetDlgItem(IDC_REC_START)->EnableWindow(false);
GetDlgItem(IDC_REC_STOP)->EnableWindow(false); 
GetDlgItem(IDC_PLAY)->EnableWindow(false); 
GetDlgItem(IDC_STOP)->EnableWindow(false); 
GetDlgItem(IDC_PAUSE)->EnableWindow(false);
GetDlgItem(IDC_CONTINUE)->EnableWindow(false);
GetDlgItem(IDC_REC_CON)->EnableWindow(false); 
GetDlgItem(IDC_REC_HOLD)->EnableWindow(false);

return TRUE; // return TRUE unless you set the focus to a control
}



void CWinceRecordDlg::OnBrowse() 
{
    // TODO: Add your control notification handler code here
    

    CString defFilter("Wave File(*.wav)|*.wav|");
CFileDialog Dlg(FALSE,NULL,NULL,OFN_HIDEREADONLY,defFilter);
    if (Dlg.DoModal() == IDCANCEL)
    return;
    m_strFile = Dlg.GetPathName();
    m_strFile+= ".wav";
    //MessageBox(m_strFile,TEXT("msg"),MB_OK);

    UpdateData(false);
        if(m_strFile!="")
    {
     GetDlgItem(IDC_REC_START)->EnableWindow(true);
    SetDlgItemText(IDC_REC_START,L"录制");
    }
    
}

void CWinceRecordDlg::OnRecStart() 
{
    // TODO: Add your control notification handler code here
        
if (m_strFile.IsEmpty())
        {
        AfxMessageBox(_T("请先输入要保存的文件名"));
        return;    
        }
UpdateData(true);

    time=GetDlgItemInt(IDC_TIME);
//参数配置
    pszFilename = m_strFile.GetBuffer(m_strFile.GetLength());;
    dwDuration =time * 1000;    // record for 5 seconds
    dwChannels = 1;           // default to mono
    dwBitsPerSample = 16;     // default to 16-bit samples
    dwSampleRate = 11025;     // default to 11.025KHz sample rate
    dwDeviceId = WAVE_MAPPER;           // capture from device 0


    pwfx=&wfx;
    wfx.cbSize = 0;
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.wBitsPerSample = (WORD) dwBitsPerSample;
    wfx.nSamplesPerSec = dwSampleRate;
    wfx.nChannels = (WORD) dwChannels;
    wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
    wfx.nAvgBytesPerSec = wfx.nBlockAlign * wfx.nSamplesPerSec;
    dwBufferSize = (dwDuration * pwfx->nSamplesPerSec / 1000) * pwfx->nBlockAlign;
    if(dwDuration==0) //如果设为不是定时的话,就开20M内存
    {
    dwBufferSize= 20000000;
    }
    // try to allocate the capture buffer
    pBufferBits = new BYTE [dwBufferSize];
    if (pBufferBits == NULL) {
        RETAILMSG (1, (TEXT("Unable to allocate %d bytes for %d ms of audio data\r\n"), dwBufferSize, dwDuration));
       
    }

    // let user know what's going on
    RETAILMSG(1, (TEXT("Recording %5d ms to \"%s\": %c%02d %5dHz (%8d bytes)\r\n")
        , dwDuration
        , pszFilename
        , pwfx->nChannels == 2 ? L'S' : L'M' 
        , pwfx->wBitsPerSample
        , pwfx->nSamplesPerSec
        , dwBufferSize
        ));



memset(&hdr, 0, sizeof(WAVEHDR));
    hdr.dwBufferLength = dwBufferSize;
    hdr.lpData = (char *) pBufferBits;


    // create an event so we know when capture is completed


    // open the wave capture device
    MMRESULT mr = waveInOpen(&hwi,WAVE_MAPPER, pwfx, (DWORD)this->m_hWnd, NULL, CALLBACK_WINDOW);//CALLBACK_WINDOW 被这个害死

    if (mr != MMSYSERR_NOERROR) {
        RETAILMSG(1, (TEXT("waveInOpen failed. mr=%08x\r\n"), mr));
     
    }
    mr = waveInPrepareHeader(hwi, &hdr, sizeof(WAVEHDR));
    // submit the buffer for capture
    mr = waveInAddBuffer(hwi, &hdr, sizeof(WAVEHDR));

    // start capturing
    RETAILMSG(1, (TEXT("Starting capture...\r\n\n\n")));
    mr = waveInStart(hwi);
    //RecordWaveBuffer(&hdr, dwDeviceId, pwfx, dwDuration);   
    //RecordWaveFile (pszFilename, dwDeviceId, pwfx, dwDuration);

GetDlgItem(IDC_REC_STOP)->EnableWindow(true); 
GetDlgItem(IDC_REC_START)->EnableWindow(false);
GetDlgItem(IDC_REC_HOLD)->EnableWindow(true);
saved=true;
str=0;
SetTimer(1,100,NULL);//设置定时器
}
void CWinceRecordDlg::OnMM_WIM_OPEN(UINT wParam, LONG lParam) 
{
    // TODO: Add your message handler code here and/or call default    
    RETAILMSG(1, (TEXT("OnMM_WIM_OPEN...\r\n\n\n")));

}

void CWinceRecordDlg::OnMM_WIM_DATA(UINT wParam, LONG lParam) 
{

    RETAILMSG(1, (TEXT("OnMM_WIM_DATA...\r\n\n\n")));

waveInReset(hwi);
waveInClose(hwi);

    // and we're done

//    RecordWaveFile(pszFilename,dwDeviceId, &wfx, dwDuration);
}



void CWinceRecordDlg::OnMM_WIM_CLOSE(UINT wParam, LONG lParam) 
{
    RETAILMSG(1, (TEXT("OnMM_WIM_CLOSE...\r\n\n\n")));        
    mr = waveInReset(hwi);
    mr = waveInUnprepareHeader(hwi, &hdr, sizeof(WAVEHDR));
    RETAILMSG(1, (TEXT("Capture completed. Writing %s\r\n"), pszFilename));
    mr = WriteWaveFile(pszFilename, pwfx, hdr.dwBytesRecorded, pBufferBits);
    

GetDlgItem(IDC_REC_STOP)->EnableWindow(false); 
GetDlgItem(IDC_PLAY)->EnableWindow(true); 
GetDlgItem(IDC_REC_START)->EnableWindow(true);
GetDlgItem(IDC_REC_CON)->EnableWindow(false); 
GetDlgItem(IDC_REC_HOLD)->EnableWindow(false); 
SetDlgItemText(IDC_REC_START,L"重录");
saved=false;
KillTimer(1);//关闭
SetDlgItemInt(IDC_STATIC_TIME,time);
    delete [] pBufferBits;
}

void CWinceRecordDlg::OnRecStop() 
{
    // TODO: Add your control notification handler code here

RETAILMSG(1, (TEXT("OnRecStop\r\n\n\n")));
waveInReset(hwi);
waveInClose(hwi);

//PostMessage(MM_WIM_CLOSE, 0, 0);

}

void CDialog::OnCancel()
{
    RETAILMSG(1, (TEXT("2.saved=%d\r\n"), saved));


if(saved==1)
    {
    RETAILMSG(1, (TEXT("3.saved=%d\r\n"), saved));
        
if(MessageBox(L"录音未保存,你要保存录音吗?",L"系统录音提示",MB_YESNO|MB_ICONQUESTION)==IDYES)
{

        
::PostMessage(m_hWnd,WM_COMMAND,MAKEWPARAM(IDC_REC_STOP,BN_CLICKED),0);   
RETAILMSG(1, (TEXT("ExitProcess(0)\r\n\n\n")));
PostQuitMessage(0); //这个最常用

}
else
{
ExitProcess(0);//这个关得最快
}
    }



    else 
    {
        ExitProcess(0);//这个关得最快
    }



}

void CWinceRecordDlg::OnPlay() 
{

hThread = CreateThread(NULL, //   no   security   attributes     
0, //   use   default   stack   size     
(LPTHREAD_START_ROUTINE)ThreadFunc,     
(LPVOID)NULL, //   可以通过这个参数传送一个参数的指针到处理函数中   
0, //   creation   flag     
&dwThreadID); //   thread   identifier     
if (hThread   ==   NULL)     
MessageBox(TEXT("创建线程出错!"),TEXT("msg"),MB_OK);



GetDlgItem(IDC_PLAY)->EnableWindow(false); 
GetDlgItem(IDC_PAUSE)->EnableWindow(true); 
GetDlgItem(IDC_STOP)->EnableWindow(true); 


        
}

void CWinceRecordDlg::OnStop() 
{
    // TODO: Add your control notification handler code here
    PlaySound(NULL,NULL,SND_FILENAME|SND_ASYNC);
    GetDlgItem(IDC_PLAY)->EnableWindow(true); 
        GetDlgItem(IDC_PAUSE)->EnableWindow(false); 
}

void CWinceRecordDlg::OnPause() 
{
    // TODO: Add your control notification handler code here

SuspendThread(hThread);
GetDlgItem(IDC_CONTINUE)->EnableWindow(true);
GetDlgItem(IDC_PAUSE)->EnableWindow(false); 
RETAILMSG(1, (TEXT("SuspendThread(hThread);\r\n\n\n")));
}

DWORD   CWinceRecordDlg::ThreadFunc(LPVOID lpVoid) //lpVoid即为创建线程时传入的参数,可以为空   
{     
//在你的线程中的处理。 
PlaySound(pszFilename,NULL,SND_FILENAME|SND_ASYNC);        
return   0;   
}

void CWinceRecordDlg::OnContinue() 
{
    // TODO: Add your control notification handler code here
    GetDlgItem(IDC_CONTINUE)->EnableWindow(false);
    GetDlgItem(IDC_PAUSE)->EnableWindow(true); 
ResumeThread(hThread);
RETAILMSG(1, (TEXT("ResumeThread(hThread);\r\n\n\n")));
}
void CWinceRecordDlg::OnTimer(UINT nIDEvent)
{

     
str+=100;
str1.Format(L"%.1f",str/1000);
SetDlgItemText(IDC_STATIC_TIME,str1+L"s");
str1.Format(L"%.1f",(str/1000)*28);
SetDlgItemText(IDC_STATIC_SIZE,str1+L"k");


//SetDlgItemText(IDC_STATIC_TIME,dura);
}

void CWinceRecordDlg::OnRecHold() 
{
    // TODO: Add your control notification handler code here
waveInStop(hwi);    
GetDlgItem(IDC_REC_CON)->EnableWindow(true); 
GetDlgItem(IDC_REC_HOLD)->EnableWindow(false); 
SetDlgItemText(IDC_REC_START,L"重录");

KillTimer(1);//关闭
}

void CWinceRecordDlg::OnRecCon() 
{
    // TODO: Add your control notification handler code here
waveInStart(hwi);
GetDlgItem(IDC_REC_HOLD)->EnableWindow(true); 
GetDlgItem(IDC_REC_CON)->EnableWindow(false); 
str+=200;
SetTimer(1,1000,NULL);//重启定时器
}

/
// WinceRecordDlg.h : header file
//

#if !defined(AFX_WINCERECORDDLG_H__99C636C1_A7B4_428B_B5E7_A3D68BD2B689__INCLUDED_)
#define AFX_WINCERECORDDLG_H__99C636C1_A7B4_428B_B5E7_A3D68BD2B689__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
static PTSTR pszFilename;
static bool saved;
/
// CWinceRecordDlg dialog

class CWinceRecordDlg : public CDialog
{
// Construction
public:
    CWinceRecordDlg(CWnd* pParent = NULL);    // standard constructor

// Dialog Data
    //{{AFX_DATA(CWinceRecordDlg)
    enum { IDD = IDD_WINCERECORD_DIALOG };
        // NOTE: the ClassWizard will add data members here
    //}}AFX_DATA

    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CWinceRecordDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL

// Implementation
protected:
    HICON m_hIcon;
WAVEFORMATEX wfx,*pwfx;
    // Generated message map functions
    //{{AFX_MSG(CWinceRecordDlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnMM_WIM_OPEN(UINT wParam,LONG lParam);
    afx_msg void OnMM_WIM_DATA(UINT wParam,LONG lParam);
    afx_msg void OnMM_WIM_CLOSE(UINT wParam,LONG lParam);
    afx_msg void OnBrowse();
    afx_msg void OnRecStart();
    afx_msg void OnRecStop();
    afx_msg void OnDestroy();
    afx_msg void OnPlay();
    afx_msg void OnStop();
    afx_msg void OnPause();
    afx_msg void OnContinue();
    afx_msg void OnTimer(UINT nIDEvent);
    afx_msg void OnRecHold();
    afx_msg void OnRecCon();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
private:
        MMRESULT RecordWaveFile(PCTSTR pszFilename, DWORD dwDeviceId, PWAVEFORMATEX pwfx, DWORD dwDuration);
    CString    m_strFile;
    int time;
MMRESULT mr;
PBYTE pBufferBits;
DWORD dwBufferSize;
WAVEHDR hdr;
DWORD dwWait;
HANDLE hevDone;
HWAVEIN hwi;
DWORD dwTolerance;
DWORD dwDuration;
DWORD dwDeviceId;           // capture from device 0

    DWORD dwChannels;
    DWORD dwBitsPerSample;
    DWORD dwSampleRate;
    static DWORD WINAPI ThreadFunc(LPVOID lpVoid);
DWORD   dwThreadID;   
HANDLE hThread;
float str; 
CString str1;

};

//{{AFX_INSERT_LOCATION}}
// Microsoft eMbedded Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_WINCERECORDDLG_H__99C636C1_A7B4_428B_B5E7_A3D68BD2B689__INCLUDED_)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值