📄 voice_net_aacdlg.cpp
字号:
// Voice_net_aacDlg.cpp : implementation file
//
#include "StdAfx.h"
#include "Voice_net_aac.h"
#include "Voice_net_aacDlg.h"
#include <afxwin.h>
#include <windef.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()
/////////////////////////////////////////////////////////////////////////////
// CVoice_net_aacDlg dialog
CVoice_net_aacDlg::CVoice_net_aacDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVoice_net_aacDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CVoice_net_aacDlg)
m_ip = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CVoice_net_aacDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVoice_net_aacDlg)
DDX_Text(pDX, IDC_EDIT_IP, m_ip);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVoice_net_aacDlg, CDialog)
//{{AFX_MSG_MAP(CVoice_net_aacDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, OnOK_IP)
ON_BN_CLICKED(IDCANCEL_IP, OnCancel_ip)
ON_BN_CLICKED(IDC_BUTTON2, OnStopConnect)
ON_BN_CLICKED(IDCANCEL2, OnCancel)
ON_BN_CLICKED(IDC_BUTTON1, OnBuidConnect)
//}}AFX_MSG_MAP
ON_MESSAGE(WM_DATACOME,OnDataCome) //有数据输入
ON_MESSAGE(WM_PLAY,OnPlay)
ON_MESSAGE(MM_WIM_DATA,OnRecordFull) //录音缓冲区满
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVoice_net_aacDlg message handlers
BOOL CVoice_net_aacDlg::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
// TODO: Add extra initialization here
//allocate memory for wave header
pWaveHdr1=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
pWaveHdr2=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
pWaveHdrOut=reinterpret_cast<PWAVEHDR>(malloc(sizeof(WAVEHDR)));
m_RecFirst=TRUE;
m_PlayFirst=TRUE;
m_ip="211.69.196.";
UpdateData(false);
return TRUE; // return TRUE unless you set the focus to a con
}
void CVoice_net_aacDlg::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 CVoice_net_aacDlg::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 CVoice_net_aacDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CVoice_net_aacDlg::OnOK_IP()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
}
void CVoice_net_aacDlg::OnCancel_ip()
{
// TODO: Add your control notification handler code here
m_ip="";
UpdateData(FALSE);
}
void CVoice_net_aacDlg::OnCancel()
{
// TODO: Add your control notification handler code here
WSACleanup();
CDialog::OnCancel();
}
CEvent ThreadEnd;
CEvent RecieveBegin;
CEvent SendBegin;
UINT Audio_Listen_Thread(LPVOID lParam) {
CVoice_net_aacDlg * pd= (CVoice_net_aacDlg *)lParam;
int lenofAcceptAddr=sizeof(pd->m_Acceptaddr),rLength;
if ((pd->m_SforVoiceOut=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)
//创建一个UDP/IP的数据报的socket
{
AfxMessageBox("Socket error!");
WSACleanup();
return -1;
}
pd->m_Acceptaddr.sin_family=AF_INET;
pd->m_Acceptaddr.sin_port=6666;
pd->m_Acceptaddr.sin_addr.s_addr=INADDR_ANY;
if( bind(pd->m_SforVoiceOut,(SOCKADDR *)&(pd->m_Acceptaddr),sizeof(pd->m_Acceptaddr) ))
{
AfxMessageBox("Voice out socket bind error!");
WSACleanup();
return -1;
}
pd->m_Acceptaddr.sin_family=AF_INET;
pd->m_Acceptaddr.sin_port=6665;
pd->m_Acceptaddr.sin_addr.s_addr=inet_addr(pd->m_ip);
//设置m_SforVoiceOut为非阻塞,当有数据到达时,发WM_DATACOME消息
if( WSAAsyncSelect(pd->m_SforVoiceOut,pd->hwnd,WM_DATACOME,FD_READ)==SOCKET_ERROR )
{
AfxMessageBox("VoiceOut socket select error");
WSACleanup();
return -1;
}
BOOL KeepRunning=TRUE;
while(KeepRunning){
::WaitForSingleObject(RecieveBegin.m_hObject,INFINITE);
// AfxMessageBox("recv");
if(pd->m_PlayFirst) //正播放第一个缓冲区,用第二个缓冲区接收
{
rLength=recvfrom( pd->m_SforVoiceOut,pd->pOutBuffer2,INP_BUFFER_SIZE,0,
(LPSOCKADDR)&(pd->m_Acceptaddr),&lenofAcceptAddr );
if(rLength==SOCKET_ERROR) { AfxMessageBox("recv error!"); return -1;}
pd->m_PlayFirst=1-pd->m_PlayFirst;
::PostMessage(pd->hwnd,WM_PLAY,0L,0);
RecieveBegin.ResetEvent();
}
//正播放第二个缓冲区,用第一个缓冲区接收
else
{
rLength=recvfrom( pd->m_SforVoiceOut,pd->pOutBuffer1,INP_BUFFER_SIZE,0,
(LPSOCKADDR)&(pd->m_Acceptaddr),&lenofAcceptAddr );
if(rLength==SOCKET_ERROR) { AfxMessageBox("recv error!"); return -1;}
pd->m_PlayFirst=1-pd->m_PlayFirst;
::PostMessage(pd->hwnd,WM_PLAY,0L,0);
RecieveBegin.ResetEvent();
}
if ( ::WaitForSingleObject(ThreadEnd.m_hObject,0)==WAIT_OBJECT_0)
KeepRunning=false;
}
return 0;
}
UINT Audio_Send_Thread(LPVOID lParam){
CVoice_net_aacDlg * pd= (CVoice_net_aacDlg *)lParam;
int lenofcalladdr=0;
if ((pd->m_SforVoiceIn=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==INVALID_SOCKET)
//创建一个UDP/IP的数据报的socket
{
AfxMessageBox("Socket error!");
WSACleanup();
return FALSE;
}
pd->m_Sendaddr.sin_family=AF_INET;
pd->m_Sendaddr.sin_port=6665;
pd->m_Sendaddr.sin_addr.s_addr=INADDR_ANY;
if( bind(pd->m_SforVoiceIn,(SOCKADDR *)&(pd->m_Sendaddr),sizeof(pd->m_Sendaddr) ))
{
AfxMessageBox("Voice out socket bind error!");
WSACleanup();
return -1;
}
pd->m_Sendaddr.sin_family=AF_INET;
pd->m_Sendaddr.sin_port=6666;
pd->m_Sendaddr.sin_addr.s_addr=inet_addr(pd->m_ip);
BOOL KeepRunning=TRUE;
while(KeepRunning){
::WaitForSingleObject(SendBegin.m_hObject,INFINITE);
if(pd->m_RecFirst)
{
//发送第一个缓冲区,此时第二个缓冲区正继续录音
int result=sendto((pd->m_SforVoiceIn), (char *)(pd->pBuffer1),INP_BUFFER_SIZE,0,(SOCKADDR *)&(pd->m_Sendaddr),sizeof(pd->m_Sendaddr));
if(result==SOCKET_ERROR) { AfxMessageBox("send erro");return -1;
}
//将第一个缓冲区加到第二个缓冲区之后
(pd->pWaveHdr1)->lpData =(char *)pd->pBuffer1;
(pd->pWaveHdr1)->dwBufferLength =INP_BUFFER_SIZE;
(pd->pWaveHdr1)->dwBytesRecorded =0L;
(pd->pWaveHdr1)->dwUser =0L;
waveInPrepareHeader((HWAVEIN)pd->hWaveIn,(LPWAVEHDR)pd->pWaveHdr1,sizeof(WAVEHDR));
waveInAddBuffer(pd->hWaveIn,pd->pWaveHdr1,sizeof(WAVEHDR));
pd->m_RecFirst=FALSE;
}
else
{
//发送第二个缓冲区,此时第一个缓冲区正继续录音
sendto(pd->m_SforVoiceIn, (char *)pd->pBuffer2,INP_BUFFER_SIZE,0,(SOCKADDR *)&(pd->m_Sendaddr),sizeof(pd->m_Sendaddr));
//将第二个缓冲区加到第一个缓冲区之后
(pd->pWaveHdr2)->lpData =(char *)pd->pBuffer2;
(pd->pWaveHdr2)->dwBufferLength =INP_BUFFER_SIZE;
(pd->pWaveHdr2)->dwBytesRecorded =0L;
(pd->pWaveHdr2)->dwUser =0L;
waveInPrepareHeader((HWAVEIN)pd->hWaveIn,(LPWAVEHDR)pd->pWaveHdr2,sizeof(WAVEHDR));
waveInAddBuffer(pd->hWaveIn,pd->pWaveHdr2,sizeof(WAVEHDR));
pd->m_RecFirst=TRUE;
}
SendBegin.ResetEvent();
if ( ::WaitForSingleObject(ThreadEnd.m_hObject,0)==WAIT_OBJECT_0)
KeepRunning=false;
}
return 0;
}
void CVoice_net_aacDlg::OnBuidConnect()
{
// TODO: Add your control notification handler code here
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 ;
}
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 ;
}
pBuffer1=(PBYTE)malloc(INP_BUFFER_SIZE);
pBuffer2=(PBYTE)malloc(INP_BUFFER_SIZE);
if (!pBuffer1 || !pBuffer2)
{
if (pBuffer1) free(pBuffer1);
if (pBuffer2) free(pBuffer2);
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox("Memory erro!");
return ;
}
//open waveform audio for input
m_waveformin.wFormatTag=WAVE_FORMAT_PCM;
m_waveformin.nChannels=2;
m_waveformin.nSamplesPerSec=44100;//采样频率
m_waveformin.nAvgBytesPerSec=44100*2;
m_waveformin.nBlockAlign=1;
m_waveformin.wBitsPerSample=16;
m_waveformin.cbSize=0;
if (waveInOpen(&hWaveIn,WAVE_MAPPER,&m_waveformin,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW))
{ //打开录音设备函数
free(pBuffer1);
free(pBuffer2);
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox("Audio can not be open!");
}
pWaveHdr1->lpData=(LPTSTR)pBuffer1;
pWaveHdr1->dwBufferLength=INP_BUFFER_SIZE;
pWaveHdr1->dwBytesRecorded=0;
pWaveHdr1->dwUser=0;
pWaveHdr1->dwFlags=0;
pWaveHdr1->dwLoops=1;
pWaveHdr1->lpNext=NULL;
pWaveHdr1->reserved=0;
waveInPrepareHeader(hWaveIn,pWaveHdr1,sizeof(WAVEHDR));
pWaveHdr2->lpData=(LPTSTR)pBuffer2;
pWaveHdr2->dwBufferLength=INP_BUFFER_SIZE;
pWaveHdr2->dwBytesRecorded=0;
pWaveHdr2->dwUser=0;
pWaveHdr2->dwFlags=0;
pWaveHdr2->dwLoops=1;
pWaveHdr2->lpNext=NULL;
pWaveHdr2->reserved=0;
waveInPrepareHeader(hWaveIn,pWaveHdr2,sizeof(WAVEHDR));
// Add the buffers
waveInAddBuffer (hWaveIn, pWaveHdr1, sizeof (WAVEHDR)) ;
waveInAddBuffer (hWaveIn, pWaveHdr2, sizeof (WAVEHDR)) ;
// Begin sampling
waveInStart (hWaveIn) ;
//放音缓冲区
pOutBuffer1 =(char *)malloc(INP_BUFFER_SIZE);
pOutBuffer2 =(char *)malloc(INP_BUFFER_SIZE);
//MessageBox("Unknown Error!","Wave Out Open",MB_ICONEXCLAMATION|MB_OK);
::AfxBeginThread(Audio_Listen_Thread,this);
::AfxBeginThread(Audio_Send_Thread,this);
m_waveformout.wFormatTag = WAVE_FORMAT_PCM;
m_waveformout.nChannels =2;
m_waveformout.nSamplesPerSec =44100;
m_waveformout.nAvgBytesPerSec =44100*2;
m_waveformout.nBlockAlign =1;
m_waveformout.wBitsPerSample =16;
m_waveformout.cbSize =0;
if (waveOutOpen(&hWaveOut,WAVE_MAPPER,&m_waveformout,(DWORD)this->m_hWnd,NULL,CALLBACK_WINDOW)) {
MessageBeep(MB_ICONEXCLAMATION);
AfxMessageBox("Audio output erro");
}
return ;
}
void CVoice_net_aacDlg::OnDataCome()
{
// MessageBox("data come");
RecieveBegin.SetEvent();
}
void CVoice_net_aacDlg::OnPlay(){
if(m_PlayFirst) pWaveHdrOut->lpData =(char *)pOutBuffer1;
else pWaveHdrOut->lpData =(char *)pOutBuffer2;
pWaveHdrOut->dwBufferLength =INP_BUFFER_SIZE;
pWaveHdrOut->dwUser =0L;
pWaveHdrOut->dwLoops =0L;
pWaveHdrOut->dwFlags =0L;
waveOutPrepareHeader((HWAVEOUT)hWaveOut,(LPWAVEHDR)pWaveHdrOut,sizeof(WAVEHDR));
waveOutWrite(hWaveOut,pWaveHdrOut,sizeof(WAVEHDR));
}
void CVoice_net_aacDlg::OnRecordFull()
{
SendBegin.SetEvent();
}
void CVoice_net_aacDlg::OnStopConnect()
{
// TODO: Add your control notification handler code here
waveInReset(hWaveIn);
waveInClose(hWaveIn);
ThreadEnd.SetEvent();
waveOutReset(hWaveOut);
waveOutClose (hWaveOut);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -