该代码是网上下载后经过修改的
发送工程文件:
// 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()
{
}