您的位置:首页 > 其它

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()
{
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐