vc 录制和发送音频并保存wav文件
2012-02-23 20:03
471 查看
该代码是网上下载后经过修改的
发送工程文件:
接收工程文件:
发送工程文件:
// SendVoiceDlg.h : header file // #if !defined(AFX_SENDVOICEDLG_H__717028C9_1E4C_11D3_A18B_0080C8E80FE6__INCLUDED_) #define AFX_SENDVOICEDLG_H__717028C9_1E4C_11D3_A18B_0080C8E80FE6__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 /* Self Define Begin */ #include <mmsystem.h> #define BLOCK_PER_BUFFER 3 #define FRAMENUM 8 #define PCMBUFFER_SIZE 360*8 #define BITBUFFER_SIZE 7*FRAMENUM /* define end */ ///////////////////////////////////////////////////////////////////////////// // CSendVoiceDlg dialog class CSendVoiceDlg : public CDialog { // Construction public: CSendVoiceDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CSendVoiceDlg) enum { IDD = IDD_SENDVOICE_DIALOG }; // NOTE: the ClassWizard will add data members here //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CSendVoiceDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; HWND hwnd; char * pInBuffer1; //录音缓冲区(char*) char * pInBuffer2; HWAVEIN hWaveIn; //设备标志 LPWAVEHDR pWaveHdr1; //设备设置头 LPWAVEHDR pWaveHdr2; MMRESULT result; WAVEFORMATEX format; int ErrormesgLen; char szOpenError[100]; BOOL m_RecFirst; SOCKET m_SforVoiceIn; SOCKADDR_IN m_Sendaddr; int lenofcalladdr; FILE *pf; char *m_dataBuf; DWORD m_dataLen; char *newbuf; BOOL m_bEnd; // Generated message map functions //{{AFX_MSG(CSendVoiceDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnSend(); afx_msg void OnRecordFull(UINT wParam,LONG lParam); afx_msg void OnCloseRecord(UINT wParam,LONG lParam); virtual void OnCancel(); //}}AFX_MSG DECLARE_MESSAGE_MAP() private: void saveFile(); }; //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(AFX_SENDVOICEDLG_H__717028C9_1E4C_11D3_A18B_0080C8E80FE6__INCLUDED_)
// SendVoiceDlg.cpp : implementation file // #include "stdafx.h" #include "SendVoice.h" #include "SendVoiceDlg.h" #include "waveform.h" #include <stdlib.h> #include <malloc.h> #include <windowsx.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSendVoiceDlg dialog CSendVoiceDlg::CSendVoiceDlg(CWnd* pParent /*=NULL*/) : CDialog(CSendVoiceDlg::IDD, pParent) { //{{AFX_DATA_INIT(CSendVoiceDlg) // 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); m_dataBuf = NULL; m_dataLen = 0; newbuf = NULL; m_bEnd = FALSE; } void CSendVoiceDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSendVoiceDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CSendVoiceDlg, CDialog) //{{AFX_MSG_MAP(CSendVoiceDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_SEND, OnSend) ON_MESSAGE(MM_WIM_DATA,OnRecordFull) //录音缓冲区满 ON_MESSAGE(MM_WIM_CLOSE, OnCloseRecord) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSendVoiceDlg message handlers BOOL CSendVoiceDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 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 //初始化SOCKET WORD m_wVersionRequested; WSADATA m_wsaData; int m_err; m_wVersionRequested = MAKEWORD( 1, 1);//version 1.1 m_err = WSAStartup( m_wVersionRequested, &m_wsaData ); if ( m_err != 0 ) { MessageBox("Can't find a usable Winsock DLL!"); WSACleanup( ); return FALSE; } if ( LOBYTE( m_wsaData.wVersion ) != 1 ||HIBYTE( m_wsaData.wVersion ) != 1 ) { MessageBox("You don't have Winsock or your Winsock version is too low!"); WSACleanup( ); return FALSE; } if ((m_SforVoiceIn=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET) //创建一个TCP/IP的数据报的socket { MessageBox("Socket error!"); WSACleanup(); return FALSE; } m_Sendaddr.sin_family=AF_INET; m_Sendaddr.sin_port=6666; // 发送数据端口 m_Sendaddr.sin_addr.s_addr=inet_addr("192.168.1.26"); // 发送目的地ip hwnd=AfxGetMainWnd()->m_hWnd; //检查设备 if(!waveInGetNumDevs()) { MessageBeep(MB_OK); MessageBox("找不到语音input设备!"); return FALSE; } if(!waveOutGetNumDevs()) { MessageBeep(MB_OK); MessageBox("找不到语音 output 设备!"); return FALSE; } //Format of voice: 16 bits,11.025kHz,mono audio format.wFormatTag =WAVE_FORMAT_PCM; //格式为PCM format.nChannels =1; //单声道 mono/立体声 format.nSamplesPerSec =11025; //采样率 format.nAvgBytesPerSec =11025; //数据率 format.nBlockAlign =1; //每样点的字节数 format.wBitsPerSample =8; //采样精度 format.cbSize =0; pWaveHdr1 =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); pWaveHdr2 =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); //录音缓冲区 pInBuffer1 =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); pInBuffer2 =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); m_RecFirst=TRUE; return TRUE; // return TRUE unless you set the focus to a control } void CSendVoiceDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CSendVoiceDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CSendVoiceDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CSendVoiceDlg::OnSend() { //OPEN AUDIO INPUT DEVICE WITH THE SAME FORMAT // 为录音打开设备环境 if(result=waveInOpen( (LPHWAVEIN)&hWaveIn,WAVE_MAPPER, (LPWAVEFORMATEX)&format,(DWORD)hwnd, 0L,CALLBACK_WINDOW) ) { //OPEN INPUT AUDIO DEVICE FAILED ,FREE ALLOCATED MEMORY if(!waveInGetErrorText(result,szOpenError,ErrormesgLen)) { MessageBeep(MB_ICONEXCLAMATION); MessageBox(szOpenError,"WaveIn Open Error",MB_ICONEXCLAMATION|MB_OK); } else { MessageBeep(MB_ICONEXCLAMATION); MessageBox("Unknown error!","Wave In Open Error",MB_ICONEXCLAMATION|MB_OK); } } // wave 文件头1 pWaveHdr1->lpData =(char *)pInBuffer1; pWaveHdr1->dwBufferLength =PCMBUFFER_SIZE; //录制音频数据大小 pWaveHdr1->dwBytesRecorded =0L; pWaveHdr1->dwUser =0L; pWaveHdr1->dwLoops =0L; pWaveHdr1->lpNext =NULL; pWaveHdr1->reserved =0L; result=waveInPrepareHeader((HWAVEIN)hWaveIn,(LPWAVEHDR)pWaveHdr1,sizeof(WAVEHDR)); // 准备头结构 result=waveInAddBuffer(hWaveIn,pWaveHdr1,sizeof(WAVEHDR)); // 准备缓冲区内存 // wave 文件头结构2 pWaveHdr2->lpData =(char *)pInBuffer2; pWaveHdr2->dwBufferLength =PCMBUFFER_SIZE; //录制音频数据大小 pWaveHdr2->dwBytesRecorded =0L; pWaveHdr2->dwUser =0L; pWaveHdr2->dwLoops =0L; pWaveHdr2->lpNext =NULL; pWaveHdr2->reserved =0L; result=waveInPrepareHeader((HWAVEIN)hWaveIn,(LPWAVEHDR)pWaveHdr2,sizeof(WAVEHDR)); result=waveInAddBuffer(hWaveIn,pWaveHdr2,sizeof(WAVEHDR)); result=waveInStart(hWaveIn); // 开始录制音频 if(result) { MessageBeep(MB_ICONEXCLAMATION); MessageBox(szOpenError,"WaveIn start Error",MB_ICONEXCLAMATION|MB_OK); } } void CSendVoiceDlg::OnRecordFull(UINT wParam,LONG lParam) { // MM_WIM_DATA 消息 录制缓冲去满时相应该消息 char *recordBuf = ((LPWAVEHDR)lParam)->lpData; int len = ((LPWAVEHDR)lParam)->dwBytesRecorded; if (NULL == recordBuf) { waveInReset(hWaveIn); return; } if (NULL == m_dataBuf){ m_dataBuf = (char *) malloc(len+1); memcpy(m_dataBuf, recordBuf, len); m_dataBuf[len]=0; m_dataLen += len; } else{ newbuf =(char *) realloc(m_dataBuf, m_dataLen+len); if (newbuf == NULL) { waveInReset(hWaveIn); return ; } m_dataBuf = newbuf; CopyMemory(m_dataBuf+m_dataLen, recordBuf, len); m_dataLen += len; } //发送第一个缓冲区,此时第二个缓冲区正继续录音 int result=sendto(m_SforVoiceIn, recordBuf,len,0,(SOCKADDR *)&m_Sendaddr,lenofcalladdr); result=waveInPrepareHeader((HWAVEIN)hWaveIn,(LPWAVEHDR)lParam,sizeof(WAVEHDR)); // 清楚缓冲内存 为下一次录音准备 result=waveInAddBuffer(hWaveIn,(LPWAVEHDR)lParam,sizeof(WAVEHDR)); // 设置缓冲内存 if (m_bEnd) { waveInClose(hWaveIn); } saveFile(); } // 保存成wav文件 void CSendVoiceDlg::OnCloseRecord(UINT wParam,LONG lParam) { saveFile(); } void CSendVoiceDlg::OnCancel() { // TODO: Add extra cleanup here m_bEnd = TRUE; waveInReset(hWaveIn); waveInUnprepareHeader(hWaveIn, pWaveHdr1, sizeof(WAVEHDR)); waveInUnprepareHeader(hWaveIn, pWaveHdr2, sizeof(WAVEHDR)); CDialog::OnCancel(); } void CSendVoiceDlg::saveFile() { ////////////////////////////////////////////////////////////////////////// CFile m_file; CFileException fileException; CString m_csFileName= "F:\\test1.wav"; m_file.Open(m_csFileName,CFile::modeCreate|CFile::modeReadWrite, &fileException); /*if (m_file.Open(m_csFileName,CFile::modeCreate|CFile::modeReadWrite, &fileException)) {MessageBox("open file"); }*/ DWORD m_WaveHeaderSize = 38; DWORD m_WaveFormatSize = 18; m_WaveFormatSize = sizeof(WAVEFORMATEX); m_file.SeekToBegin(); // riff block m_file.Write("RIFF",4); //unsigned int Sec=(sizeof + m_WaveHeaderSize); unsigned int Sec=(sizeof m_dataBuf + m_WaveHeaderSize); // 整个wav文件大小 - 8 (RIFF+SIZE) m_file.Write(&Sec,sizeof(Sec)); m_file.Write("WAVE",4); // fmt block m_file.Write("fmt ",4); m_file.Write(&m_WaveFormatSize, sizeof(m_WaveFormatSize)); // m_file.Write(&format.wFormatTag, sizeof(format.wFormatTag)); // m_file.Write(&format.nChannels, sizeof(format.nChannels)); // m_file.Write(&format.nSamplesPerSec, sizeof(format.nSamplesPerSec)); // m_file.Write(&format.nAvgBytesPerSec, sizeof(format.nAvgBytesPerSec)); // m_file.Write(&format.nBlockAlign, sizeof(format.nBlockAlign)); // m_file.Write(&format.wBitsPerSample, sizeof(format.wBitsPerSample)); // m_file.Write(&format.cbSize, sizeof(format.cbSize)); m_file.Write(&format, sizeof(WAVEFORMATEX)); // data block m_file.Write("data",4); m_file.Write(&m_dataLen,sizeof(DWORD)); m_file.Write(m_dataBuf,m_dataLen); m_file.Seek(m_dataLen,CFile::begin); m_file.Close(); return ; }
接收工程文件:
// RecieveVoiceDlg.h : header file // #if !defined(AFX_RECIEVEVOICEDLG_H__717028D7_1E4C_11D3_A18B_0080C8E80FE6__INCLUDED_) #define AFX_RECIEVEVOICEDLG_H__717028D7_1E4C_11D3_A18B_0080C8E80FE6__INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 #include <mmsystem.h> #define BLOCK_PER_BUFFER 3 #define FRAMENUM 8 #define PCMBUFFER_SIZE 360*8 #define WM_DATACOME WM_USER+1 #define WM_PLAY WM_USER+2 ///////////////////////////////////////////////////////////////////////////// // CRecieveVoiceDlg dialog class CRecieveVoiceDlg : public CDialog { // Construction public: CRecieveVoiceDlg(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CRecieveVoiceDlg) enum { IDD = IDD_RECIEVEVOICE_DIALOG }; // NOTE: the ClassWizard will add data members here //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CRecieveVoiceDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; HWND hwnd; void OnDataCome(); void OnPlay(); char * pOutBuffer1; //放音缓冲区 char * pOutBuffer2; char * rBuffer; //接收缓冲区 No USE HWAVEOUT hWaveOut; LPWAVEHDR pWaveHdr1; //设备设置头 LPWAVEHDR pWaveHdr2; LPWAVEHDR pWaveOutHdr; // 放音文件头 MMRESULT result; PCMWAVEFORMAT pcm; int ErrormesgLen; char szOpenError[100]; BOOL m_PlayFirst; SOCKET m_SforVoiceOut; SOCKADDR_IN m_Acceptaddr; // Generated message map functions //{{AFX_MSG(CRecieveVoiceDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnRecieve(); afx_msg void OnAbout(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(AFX_RECIEVEVOICEDLG_H__717028D7_1E4C_11D3_A18B_0080C8E80FE6__INCLUDED_)
// RecieveVoiceDlg.cpp : implementation file // #include "stdafx.h" #include "RecieveVoice.h" #include "RecieveVoiceDlg.h" #include <stdlib.h> #include <malloc.h> #include <windowsx.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRecieveVoiceDlg dialog CRecieveVoiceDlg::CRecieveVoiceDlg(CWnd* pParent /*=NULL*/) : CDialog(CRecieveVoiceDlg::IDD, pParent) { //{{AFX_DATA_INIT(CRecieveVoiceDlg) // 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 CRecieveVoiceDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CRecieveVoiceDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CRecieveVoiceDlg, CDialog) //{{AFX_MSG_MAP(CRecieveVoiceDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON_RECIEVE, OnRecieve) ON_BN_CLICKED(IDC_BUTTON_ABOUT, OnAbout) //}}AFX_MSG_MAP ON_MESSAGE(WM_DATACOME,OnDataCome) //有数据输入 ON_MESSAGE(WM_PLAY,OnPlay) //放音缓冲区满 END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CRecieveVoiceDlg message handlers BOOL CRecieveVoiceDlg::OnInitDialog() { CDialog::OnInitDialog(); CAboutDlg AboutDlg1; // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 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 hwnd=AfxGetMainWnd()->m_hWnd; //SOCKET初始化 WORD m_wVersionRequested; WSADATA m_wsaData; int m_err; m_wVersionRequested = MAKEWORD( 1, 1);//version 1.1 m_err = WSAStartup( m_wVersionRequested, &m_wsaData ); if ( m_err != 0 ) { MessageBox("Can't find a usable Winsock DLL!"); WSACleanup( ); return FALSE; } if ( LOBYTE( m_wsaData.wVersion ) != 1 ||HIBYTE( m_wsaData.wVersion ) != 1 ) { MessageBox("You don't have Winsock or your Winsock version is too low!"); WSACleanup( ); return FALSE; } //检查设备 if(!waveInGetNumDevs()) { MessageBeep(MB_OK); MessageBox("找不到语音input设备!"); return FALSE; } if(!waveOutGetNumDevs()) { MessageBeep(MB_OK); MessageBox("找不到语音 output 设备!"); return FALSE; } //Format of voice: 16 bits,11.025kHz,mono audio // 音频格式 pcm.wf.wFormatTag =WAVE_FORMAT_PCM; //格式为PCM pcm.wf.nChannels =1; //单声道 mono pcm.wf.nSamplesPerSec =11025; //采样率 pcm.wf.nAvgBytesPerSec =11025; //数据率 pcm.wf.nBlockAlign =1; //每样点的字节数 pcm.wBitsPerSample =8; //采样精度 // 分配内存 pWaveOutHdr =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); pWaveHdr1 =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); pWaveHdr2 =(LPWAVEHDR)GlobalAllocPtr(GHND|GMEM_SHARE,sizeof(WAVEHDR)); //放音缓冲区 pOutBuffer1 =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE*BLOCK_PER_BUFFER+500); pOutBuffer2 =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE*BLOCK_PER_BUFFER+500); //接收缓冲区 rBuffer =(char *)GlobalAllocPtr(GHND|GMEM_SHARE,PCMBUFFER_SIZE); m_PlayFirst=TRUE; return TRUE; // return TRUE unless you set the focus to a control } void CRecieveVoiceDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CRecieveVoiceDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CRecieveVoiceDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } // 接收按钮消息 void CRecieveVoiceDlg::OnRecieve() { if ((m_SforVoiceOut=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET) //创建一个TCP/IP的数据报的socket { MessageBox("Socket error!"); WSACleanup(); return ; } m_Acceptaddr.sin_family=AF_INET; m_Acceptaddr.sin_port=6666; // 本机端口 m_Acceptaddr.sin_addr.s_addr=INADDR_ANY; // 本机地址 if( bind(m_SforVoiceOut,(SOCKADDR *)&m_Acceptaddr,sizeof(m_Acceptaddr) )) // 绑定主机 将主机设为服务器 { MessageBox("Voice out socket bind error!"); return; } m_Acceptaddr.sin_family=AF_INET; m_Acceptaddr.sin_port=6666; m_Acceptaddr.sin_addr.s_addr=inet_addr("192.168.1.26"); //设置m_SforVoiceOut为非阻塞,当有数据到达时,发WM_DATACOME消息 if( WSAAsyncSelect(m_SforVoiceOut,hwnd,WM_DATACOME,FD_READ)==SOCKET_ERROR ) { MessageBox("VoiceOut socket select error"); WSACleanup(); return ; } //OPEN AUDIO OUTPUT DEVICE WITH THE SAME FORMAT // 为放音打开设备 if(result=waveOutOpen( (LPHWAVEOUT)&hWaveOut,WAVE_MAPPER, (LPWAVEFORMATEX)&pcm.wf,(DWORD)hwnd, 0L,CALLBACK_WINDOW) ) { char info[100]; MessageBox( itoa(result,info,10) ); //OPEN OUTPUT AUDIO DEVICE FAILED ,FREE ALLOCATED MEMORY if(!waveOutGetErrorText(result,szOpenError,ErrormesgLen)) { MessageBeep(MB_ICONEXCLAMATION); MessageBox(szOpenError,"Wave Out Open",MB_ICONEXCLAMATION|MB_OK); } else { MessageBeep(MB_ICONEXCLAMATION); MessageBox("Unknown Error!","Wave Out Open",MB_ICONEXCLAMATION|MB_OK); } } } // 接收数据 void CRecieveVoiceDlg::OnDataCome() { //正播放第一个缓冲区,用第二个缓冲区接收 if(m_PlayFirst) { int lenofAcceptAddr,rLength; rLength=recvfrom( m_SforVoiceOut,pOutBuffer2,PCMBUFFER_SIZE,0, (LPSOCKADDR)&m_Acceptaddr,&lenofAcceptAddr ); if(rLength==SOCKET_ERROR) return; m_PlayFirst=1-m_PlayFirst; ::PostMessage(hwnd,WM_PLAY,0L,0); } //正播放第二个缓冲区,用第一个缓冲区接收 else { int lenofAcceptAddr,rLength; rLength=recvfrom( m_SforVoiceOut,pOutBuffer1,PCMBUFFER_SIZE,0, (LPSOCKADDR)&m_Acceptaddr,&lenofAcceptAddr ); if(rLength==SOCKET_ERROR) return; m_PlayFirst=1-m_PlayFirst; ::PostMessage(hwnd,WM_PLAY,0L,0); } } void CRecieveVoiceDlg::OnPlay() { if(m_PlayFirst) pWaveOutHdr->lpData =(char *)pOutBuffer1; else pWaveOutHdr->lpData =(char *)pOutBuffer2; pWaveOutHdr->dwBufferLength =PCMBUFFER_SIZE; pWaveOutHdr->dwUser =0L; pWaveOutHdr->dwLoops =0L; pWaveOutHdr->dwFlags =0L; result=waveOutPrepareHeader((HWAVEOUT)hWaveOut,(LPWAVEHDR)pWaveOutHdr,sizeof(WAVEHDR)); result=waveOutWrite(hWaveOut,pWaveOutHdr,sizeof(WAVEHDR)); // 播放数据 } void CRecieveVoiceDlg::OnAbout() { }
相关文章推荐
- 声音的录制(VC)(保存为WAV文件) (转)
- Android音频处理——通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能
- Android音频处理之通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能
- vc简单录、放音并保存为wav文件程序(附vc源代码)
- 【转载】iOS麦克风录制音频并保存成mp3文件的Demo
- Android音频处理——通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能
- Android音频处理——通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能
- 科大迅飞使用arecord录制唤醒音频文件awake.wav
- Windows Phone 8初学者开发—第20部分:录制Wav音频文件
- 使用FlashWavRecorder实现浏览器录制wav音频和上传音频文件,兼容IE8以上浏览器
- Windows Phone 8初学者开发—第20部分:录制Wav音频文件
- Android音频处理——通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能
- WAV音频文件结构及录制
- 使用FlashWavRecorder实现浏览器录制wav音频和上传音频文件,兼容IE8以上浏览器
- Windwos平台上ffmpeg解码音频并且保存到wav文件中
- 使用Swift,录制并保存音频文件
- FFMPEG解复用、解码测试,音频保存WAV文件,视频保存为PPM图像
- WP8录制Wav音频文件
- Android音频处理——通过AudioRecord去保存PCM文件进行录制,播放,停止,删除功能
- 把音频数据保存 wav文件, save audio data to wav file