⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cvoicechatdlg.cpp

📁 CVoiceChat.rar.局域网音频聊天软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		return ;
	}
	if(m_clientstate==false)
	{
		PlaySound(NULL,NULL,NULL);//呼叫方在建立连接之前结束了呼叫
	}
	//关闭语音传输通道,关闭音频设备
}

void CCVoiceChatDlg::OnOK() 
{
	// TODO: Add extra validation here
	Listensock.Close();
	if( bwavedeviceInit==true){
		for(int Exit=0;Exit<=1;Exit++)
		{      
			delete pWaveHdrIn[Exit] ;
			delete pWaveHdrOut[Exit] ;
			free(pBufferIn[Exit]);
			free(pBufferOut[Exit]) ;
			waveInUnprepareHeader (hWaveIn, pWaveHdrIn[Exit], sizeof (WAVEHDR)) ;
			waveOutUnprepareHeader (hWaveOut, pWaveHdrOut[Exit], sizeof (WAVEHDR)) ;
		}
		// 关闭音频设备
		waveInClose (hWaveIn);
		waveOutClose(hWaveOut);
	}
   //关闭线程
   //清空队列
   sendlist.deleteall();
   recvlist.deleteall();
   Sleep(10);
   
   ::TerminateThread(sendthread,0);
   ::TerminateThread(recvthread,0);
   ::WSACleanup();
   CDialog::OnOK();
}

void CCVoiceChatDlg::OnCancel() 
{
	// TODO: Add extra cleanup here
	
	CDialog::OnCancel();
}

void CCVoiceChatDlg::OnAccept()
{
	m_link.EnableWindow(false);
	m_agreen.EnableWindow(true);
	m_abjust.EnableWindow(true);
	UINT port=5050;
	UpdateData(true);
	//用于获得套接字连接的IP地址。
	Contrlsock->GetPeerName(m_clientIP,port);
	//int len=sizeof(client);
	//Contrlsock->GetPeerName((sockaddr *)&client,&len);
	m_info = m_clientIP;
	m_info += "请求语音聊天.........\n";
	UpdateData(false);
	//播放提示语音
	//PlaySound("../PhoneIn.wav",NULL,SND_SYNC|SND_LOOP| SND_ASYNC);
    
}
//接受客户端的控制信息,调整压缩比,提示对方的状态
void CCVoiceChatDlg::SerRecvCtrlnfo()
{
	char buf[50];
	Contrlsock->Receive(buf,50,0);
	CString str;
	str=buf;
	if(str.Compare("对方终止了聊天..........")==0)
	{
		UpdateData(true);
		m_info=str;
		UpdateData(false);
		sendlist.deleteall();
		recvlist.deleteall();
		Sleep(10);
		::SuspendThread(sendthread);
		::SuspendThread(recvthread);
		m_serverstate=false;
		bDisconnectState=true;
		Contrlsock->Close();
		Contrlsock=new CServerSock;
		::closesocket(m_datasock);
		return ;
	}

}
//接受服务端的控制信息,调整压缩比,提示对方的状态
void CCVoiceChatDlg::ClientRecvCtrlnfo()
{
    char buf[50];
	Clientsock->Receive(buf,50,0);
	CString str;
	str=buf;
	
	if(str.Compare("电话已接听!!")==0)
	{
		PlaySound(NULL,NULL,NULL);
		m_clientstate=true;
		bDisconnectState=false;
		UpdateData(true);
		m_info=str;
		UpdateData(false);
		//建立语音传输通道
		if(SetDataSock())
		{
			return ;
		}
		//添加初始化音频函数
		if( bwavedeviceInit==false)InitAudioDevice();
			
		//开始录音
		RecordBegin();
		//启动发送与放音线程
		::ResumeThread(sendthread);
		::ResumeThread(recvthread);
	
	}
	if(str.Compare("对方拒绝了你的请求!!!")==0)
	{
		PlaySound(NULL,NULL,NULL);
		m_link.EnableWindow(true);
		m_end.EnableWindow(false);
		UpdateData(true);
		m_info=str;
		UpdateData(false);
		m_clientstate=false;
		Clientsock->Close();//关闭套接字
		Clientsock=new CClientSock;
	}
	if(str.Compare("对方终止了聊天..........")==0)
	{
		m_link.EnableWindow(true);
		m_end.EnableWindow(false);
		UpdateData(true);
		m_info=str;
		UpdateData(false);
		m_clientstate=false;
		Clientsock->Close();
		Clientsock=new CClientSock;
		::closesocket(m_datasock);
		
		//清空发送与接受队列,睡眠5秒挂起线程
		sendlist.deleteall();
		recvlist.deleteall();
		Sleep(10);
		::SuspendThread(sendthread);
		::SuspendThread(recvthread);
	}
}
//设置语音传输通道
int CCVoiceChatDlg::SetDataSock()
{
   m_datasock=socket(AF_INET,SOCK_DGRAM,0);
   if(m_datasock<0)
	{
		AfxMessageBox("创建UDP的套接字失败");
	}
   server.sin_addr.S_un.S_addr=inet_addr(LocalIP);//转换点分格式IP为in_addr结构体
   server.sin_family=AF_INET;
   server.sin_port=htons(5050);
   if(bind(m_datasock,(sockaddr *)&server,sizeof(server))!=0)
   {
	     closesocket(m_datasock);
         AfxMessageBox("绑定不成功,将退出!!"); 	
	   	 return 0;
   }
   if(WSAAsyncSelect(m_datasock,this->m_hWnd,UM_SOCK,FD_READ|FD_WRITE|FD_CLOSE)==SOCKET_ERROR)
   {
	   AfxMessageBox("函数WSAAsyncSelect()出错");
		return 0;
   }
   if(m_clientstate==true)
   {
	   server.sin_addr.S_un.S_addr=inet_addr(m_serverIP);
   }
   if(m_serverstate==true)
   {
	   //server.sin_addr.S_un.S_addr=inet_addr(m_clientIP);
	   server.sin_addr.S_un.S_addr=inet_addr(m_clientIP);//("202.193.60.242");
   }
   return 1;
}

void CCVoiceChatDlg::ONDATASOCKETPRC(UINT wParam,LONG lParam)
{
	switch(lParam)
	{
	case FD_READ:
		{
			//接受数据放入接受队列
			char *buffer=new char[4096];
			int len=sizeof(sockaddr);
			::recvfrom(m_datasock,buffer,4096,0,(sockaddr *)&server,&len);
			CQueueItem *item=new CQueueItem;
			item->data=buffer;
			//将数据放入接受队列
			recvlist.InsertItem(item);
			
		}
		break;
	case FD_WRITE:
		break;
	case FD_CLOSE:
		{
		}
		break;
	default:
		
		break;
	}
	
}

bool CCVoiceChatDlg::InitAudioDevice()
{
	// 初始化waveform
	waveform.wFormatTag      = WAVE_FORMAT_PCM ;  // 采样方式,PCM(脉冲编码调制)
    waveform.nChannels       = 2 ;                // 双声道
    waveform.nSamplesPerSec  = 11025 ;            // 采样率11.025KHz
    waveform.nAvgBytesPerSec = 11025;             // 数据率11.025KB/s
    waveform.nBlockAlign     = 2 ;   // 最小块单元,wBitsPerSample×nChannels/8
    waveform.wBitsPerSample  = 8 ;                // 样本大小为8bit
    waveform.cbSize          = 0 ;                // 附加格式信息
    
	// 准备pWaveHdrIn和pWaveHdrOut
	for(int HdrNum=0;HdrNum<=1;HdrNum++)
	{
        // 为缓冲区分配内存
		pBufferIn[HdrNum]  = (PBYTE)malloc (INP_BUFFER_SIZE) ;   
        pBufferOut[HdrNum] = (PBYTE)malloc (INP_BUFFER_SIZE) ;
		 if (!pBufferIn[HdrNum] || !pBufferOut[HdrNum])
		{
             if (pBufferIn[HdrNum])
		         free (pBufferIn[HdrNum]) ;
             if (pBufferOut[HdrNum])
		         free (pBufferIn[HdrNum]) ;
	         AfxMessageBox(_T("内存分配失败!"),MB_ICONINFORMATION|MB_OK,NULL);
        }

		pWaveHdrIn[HdrNum] =new WAVEHDR;
        pWaveHdrOut[HdrNum]=new WAVEHDR;

		pWaveHdrOut[HdrNum]->lpData          = (char *)pBufferIn[HdrNum];
        pWaveHdrOut[HdrNum]->dwBufferLength  = INP_BUFFER_SIZE ;
        pWaveHdrOut[HdrNum]->dwBytesRecorded = 0 ;
        pWaveHdrOut[HdrNum]->dwUser          = 0 ;
        pWaveHdrOut[HdrNum]->dwFlags         = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
        pWaveHdrOut[HdrNum]->dwLoops         = 1;
        pWaveHdrOut[HdrNum]->lpNext          = NULL ;
        pWaveHdrOut[HdrNum]->reserved        = 0 ;

	    pWaveHdrIn[HdrNum]->lpData           = (char *)pBufferOut[HdrNum] ;
    	pWaveHdrIn[HdrNum]->dwBufferLength   = INP_BUFFER_SIZE ;
	    pWaveHdrIn[HdrNum]->dwBytesRecorded  = 0 ;
	    pWaveHdrIn[HdrNum]->dwUser           = 0 ;
	    pWaveHdrIn[HdrNum]->dwFlags          = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
	    pWaveHdrIn[HdrNum]->dwLoops          = 1 ;
	    pWaveHdrIn[HdrNum]->lpNext           = NULL ;
	    pWaveHdrIn[HdrNum]->reserved         = 0 ;	

	}
	// 打开播放波形音频设备
	MMRESULT result;
	result=waveOutOpen (&hWaveOut, WAVE_MAPPER, &waveform, 
                     (DWORD) pDlg->m_hWnd, 0, CALLBACK_WINDOW);
    // 打开录制波形音频设备
	if(result==MMSYSERR_NOERROR)
	   result=waveInOpen (&hWaveIn, WAVE_MAPPER, &waveform, 
			          (DWORD) pDlg->m_hWnd, 0, CALLBACK_WINDOW);
	// 为播放和录音准备
    for(int Prepare=0;Prepare<=1;Prepare++)		
	{
	    if(result==MMSYSERR_NOERROR)
		   result=waveOutPrepareHeader(hWaveOut, pWaveHdrOut[Prepare], 
		                                sizeof (WAVEHDR)) ;
		if(result==MMSYSERR_NOERROR)
		   result=waveInPrepareHeader(hWaveIn, pWaveHdrIn[Prepare], 
		                                sizeof (WAVEHDR)) ;	
	} 
	// 设置音量为最大
	//if(result==MMSYSERR_NOERROR)
      // result=waveOutSetVolume(hWaveOut,65535);
	// 成功返回TRUE
	if(result==MMSYSERR_NOERROR)
    { 
	   bwavedeviceInit=true;
	   return TRUE;	
	}
	else
	{
	   AfxMessageBox(_T("打开波形音频设备时发生错误!"),MB_ICONINFORMATION | MB_OK,NULL);
       return FALSE;
	}
	 bwavedeviceInit=true;
	return true;
}

void CCVoiceChatDlg::RecordBegin()
{

     // 准备录音缓冲区
     waveInAddBuffer (hWaveIn, pWaveHdrIn[nOut], sizeof (WAVEHDR)) ;
	 // 开始录音
     waveInStart (hWaveIn) ;
}

void CCVoiceChatDlg::ON_MM_WIM_OPEN()
{
	AfxMessageBox("打开录音设备成功!");
}
void CCVoiceChatDlg::ON_MM_WIM_DATA()//录音开始后,每当有采样数据填满数据块后
									//设备驱动程序就会发消息MM_WIM_DATA给用户窗口
{
	  // 将音频数据放入队列
	  CQueueItem *item=new CQueueItem;
	  char *buffer=new char[4096];
	  memcpy(buffer,pBufferOut[nOut],4096);
	  item->data=buffer;
	  sendlist.InsertItem(item);
	  //memset(pBufferOut[nOut],0,4096);
	  // 缓冲区循环
	  nOut=1-nOut;	
	  //if (bDisconnectState==TRUE)//判断连接是否已经断开
	  //{
        //  waveInClose(hWaveIn) ;
	  //}
	  //else
      //{
		  // 开始下一轮录音
		  RecordBegin();
	  //}
}
void CCVoiceChatDlg::ON_MM_WIM_CLOSE()
{
	 waveInUnprepareHeader(hWaveIn, pWaveHdrIn[0], sizeof (WAVEHDR)) ;
	 waveInUnprepareHeader(hWaveIn, pWaveHdrIn[1], sizeof (WAVEHDR)) ;
	 waveInClose (hWaveIn); 	 
	 hWaveIn=NULL; //clear it   
}
void CCVoiceChatDlg::ON_MM_WOM_OPEN()
{
}
DWORD WINAPI ThreadSendPro(LPVOID lp)
{
	
	while(1)
	{
		char *buffer;
		while(1)
		{
			if(pDlg->sendlist.Itemnum()>0)break;
			//::Sleep(1);
		}
        buffer=pDlg->sendlist.TakeOutItem();
        //添加数据压缩代码
		int ret=::sendto(pDlg->m_datasock,buffer,4096,0,(sockaddr *)&server,sizeof(sockaddr));
		delete(buffer);
	}
	return 0;
}
DWORD WINAPI ThreadRecvPro(LPVOID lp)
{
	while(1)
	{
		char *buffer;
		while(1)
		{
			
			if(pDlg->recvlist.Itemnum()>0)break;
			//::Sleep(1);
		}
		buffer=pDlg->recvlist.TakeOutItem();
		//对数据进行解压缩还原
		memcpy(pBufferIn[nIn],buffer,strlen(buffer));
		//播放音频
		waveOutWrite (hWaveOut, pWaveHdrOut[nIn], sizeof (WAVEHDR)) ;
		//清空缓冲区
		//memset(pBufferIn[nIn],0,4096);
	    nIn=1-nIn;
		delete(buffer);
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -