64,654
社区成员
发帖
与我相关
我的任务
分享
DWORD CALLBACK CAudioChat::RecvThread(LPVOID lpParameter)
{
CAudioChat *p=(CAudioChat *)lpParameter;
if(p==NULL) return -1;
while(true)
{
p->RecvAudio();
if(!p->IsMySelfAudio())
p->RecvQueue.push(RecvData);
}
return 0;
}
void CAudioChat::CreateOutThread()
{
hRecvThread=CreateThread(NULL,0,RecvThread,this,0,NULL);
}
类似这个样子
#include "CAudioChat.h"
#include <Windows.h>
#include <MMSystem.h>
#include <cstring>
CAudioChat::CAudioChat()
{
InitSockData();
ConnectToServer();
InitWaveOut();
InitWaveIn();
IsTimeOut=false;
IsSpeakFinsh=false;
GetHostIP();
CreateBroadRecv();
}
CAudioChat::~CAudioChat()
{
delete []InWaveHdr.lpData;
}
void CAudioChat::TransLastError(DWORD ErrCode)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,\
NULL,ErrCode,0,(LPSTR)&lpMsgBuf,0,NULL);
cout<<lpMsgBuf<<endl;
}
void CAudioChat::InitSockData()
{
WSADATA wsaData;
WORD sockVersion=MAKEWORD(2,0);
WSAStartup(sockVersion,&wsaData);
}
void CAudioChat::GetHostIP()
{
char HostName[56];
gethostname(HostName,sizeof(HostName)*sizeof(char));
for(int i=0;i<5;i++)
{
ZeroMemory(HostIP[i],sizeof(HostIP[i]));
}
struct hostent *HostInfo;
int i=0;
if((HostInfo=gethostbyname(HostName)) != NULL)
{
while(HostInfo->h_addr_list[i])
{
strcpy_s(HostIP[i],inet_ntoa(*(struct in_addr*)HostInfo->h_addr_list[i]));
i++;
}
}
}
DWORD CAudioChat::SendAudio()
{
strncpy_s(SendData.Data,InWaveHdr.lpData,InWaveHdr.dwBufferLength-200);
SendData.dwBufferLenght=InWaveHdr.dwBufferLength;
DWORD nSend=0;
nSend=sendto(sSend,(char *)&SendData,sizeof(SendData),0,(sockaddr *)&sin_Send,sizeof(sin_Send));
return nSend;
}
void CAudioChat::PlayAudio()
{
waveOutPrepareHeader(hWaveOut,&OutWaveHdr,sizeof(WAVEHDR));
waveOutPause(hWaveOut);
waveOutWrite(hWaveOut,&OutWaveHdr,sizeof(WAVEHDR));
waveOutRestart(hWaveOut);
MSG msg;
while(true)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT)
break;
}
else
{
WaitMessage();
}
}
}
DWORD CAudioChat::RecvAudio()
{
DWORD nRecv;
int nLen=sizeof(sin_Recv);
nRecv=recvfrom(sRecv,(char *)&RecvData,sizeof(struct protocol),0,(sockaddr *)&sin_Recv,&nLen);
return nRecv;
}
int CAudioChat::ConnectToServer(const char *Address,const int Port)
{
sServer=socket(AF_INET,SOCK_STREAM,0);
sin_server.sin_family=AF_INET;
sin_server.sin_port=htons(Port);
sin_server.sin_addr.S_un.S_addr=inet_addr(Address);
int ret=connect(sServer,(sockaddr*)&sin_server,sizeof(struct sockaddr_in));
if(ret != -1)
SendUserInfo();
else
TransLastError(WSAGetLastError());
return ret;
}
void CAudioChat::SendUserInfo(const char *name,const int priority)
{
send(sServer,name,strlen(name),0);
send(sServer,(char *)&priority,sizeof(int),0);
}
int CAudioChat::CreateBroadSend()
{
sSend=socket(AF_INET,SOCK_DGRAM,0);
BOOL bBroadCast=TRUE;
sin_Send.sin_family=AF_INET;
sin_Send.sin_addr.S_un.S_addr=INADDR_BROADCAST;
sin_Send.sin_port=htons(SERVER_PORT);
setsockopt(sSend,SOL_SOCKET,SO_BROADCAST,(char *)&bBroadCast,sizeof(BOOL));
return 0;
}
int CAudioChat::CreateBroadRecv()
{
sRecv=socket(AF_INET,SOCK_DGRAM,0);
sin_Recv.sin_family=AF_INET;
sin_Recv.sin_addr.S_un.S_addr=INADDR_ANY;
sin_Recv.sin_port=htons(SERVER_PORT);
return (bind(sRecv,(sockaddr *)&sin_Recv,sizeof(sin_Recv))==SOCKET_ERROR);
}
void CAudioChat::InitWaveFormat()
{
wfx.wFormatTag=WAVE_FORMAT_PCM;
wfx.nChannels=1;
wfx.nSamplesPerSec=5000;
wfx.nAvgBytesPerSec=5000;
wfx.nBlockAlign=1;
wfx.wBitsPerSample=8;
wfx.cbSize=0;
}
void CAudioChat::InitInWaveHdr()
{
InWaveHdr.lpData=new char[ALLOC_BUF];
InWaveHdr.dwBufferLength=ALLOC_BUF*sizeof(char);
InWaveHdr.dwBytesRecorded=0;
InWaveHdr.dwUser=0;
InWaveHdr.dwFlags=0;
InWaveHdr.dwLoops=0;
}
void CAudioChat::InitOutWaveHdr()
{
OutWaveHdr.lpData=NULL;
OutWaveHdr.dwBufferLength=0;
OutWaveHdr.dwBytesRecorded=0;
OutWaveHdr.dwUser=0;
OutWaveHdr.dwFlags=0;
OutWaveHdr.dwLoops=0;
}
void CAudioChat::InitWaveIn()
{
InitWaveFormat();
InitInWaveHdr();
waveInOpen(&hWaveIn,WAVE_MAPPER,&wfx,NULL,0L,CALLBACK_NULL);
}
void CAudioChat::WaveInBuf()
{
waveInPrepareHeader(hWaveIn,&InWaveHdr,sizeof(WAVEHDR));
waveInAddBuffer(hWaveIn,&InWaveHdr,sizeof(WAVEHDR));
}
void CAudioChat::BeginRecord(const int nTime)
{
MMTIME mmt;
WaveInBuf();
waveInStart(hWaveIn);
Sleep(nTime);
waveInGetPosition(hWaveIn,&mmt,sizeof(MMTIME));
waveInReset(hWaveIn);
InWaveHdr.dwBufferLength=mmt.u.cb;
waveInUnprepareHeader(hWaveIn,&InWaveHdr,sizeof(WAVEHDR));
}
void CAudioChat::waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2)
{
switch(uMsg)
{
case WOM_DONE:
cout<<"Done"<<endl;
PostThreadMessage(OutAudioThreadID,WM_QUIT,0,0);
break;
case WOM_OPEN:
break;
case WOM_CLOSE:
break;
default:
break;
}
}
bool CAudioChat::IsPlay()
{
return (RecvQueue.front().Channel==CurrentChannel);
}
void CAudioChat::InitWaveOut()
{
InitWaveFormat();
InitOutWaveHdr();
waveOutOpen(&hWaveOut,WAVE_MAPPER,&wfx,(DWORD)waveOutProc,0,CALLBACK_FUNCTION);
}
bool CAudioChat::IsMySelfAudio()
{
int i=0;
while(HostIP[i][0] && i<5)
{
if(!strcmp(HostIP[i],inet_ntoa(sin_Recv.sin_addr)))
return true;
}
return false;
}
DWORD CALLBACK CAudioChat::OutAudioThread(LPVOID lpParameter)
{
OutAudioThreadID=GetCurrentThreadId();
bool isFirst=true;
while(true)
{
if(!RecvQueue.empty())
{
if(isFirst)
{
if(IsPlay())
{
OutWaveHdr.lpData=RecvQueue.front().Data;
OutWaveHdr.dwBufferLength=RecvQueue.front().dwBufferLenght;
PlayAudio();
}
}
isFirst=!isFirst;
RecvQueue.pop();
}
}
return 0;
}
DWORD CALLBACK CAudioChat::InAudioThread(LPVOID lpParameter)
{
while(true)
{
if(IsTimeOut || IsSpeakFinsh)
break;
BeginRecord();
SendData.dwBufferLenght=InWaveHdr.dwBufferLength;
strncpy_s(SendData.Data,InWaveHdr.lpData,InWaveHdr.dwBufferLength-200);
SendAudio();
}
return 0;
}
DWORD CALLBACK CAudioChat::RecvThread(LPVOID lpParameter)
{
while(true)
{
RecvAudio();
if(!IsMySelfAudio())
RecvQueue.push(RecvData);
}
return 0;
}
void CAudioChat::CreateOutThread()
{
hOutAudio=CreateThread(NULL,0,OutAudioThread,NULL,0,NULL);
hRecvThread=CreateThread(NULL,0,RecvThread,NULL,0,NULL);
}
class CAudioChat
{
public:
CAudioChat();
~CAudioChat();
/************************************************************************/
/* NetWork Public Function */
/************************************************************************/
static int CreateBroadSend();
static int CreateBroadRecv();
void CreateOutThread();
void CreateInThread();
static DWORD SendAudio();
static DWORD RecvAudio();
static void PlayAudio();
/************************************************************************/
/* Audio Function */
/************************************************************************/
static void BeginRecord(const int nTime=500);
static void waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
private:
/************************************************************************/
/* NetWork Private Function */
/************************************************************************/
void InitSockData(void);
void GetHostIP();
int ConnectToServer(const char *Address="210.34.158.99",const int Port=SERVER_PORT);
void SendUserInfo(const char *name="NoName",const int priority=10);
/************************************************************************/
/* Audio Private Function */
/************************************************************************/
static DWORD CALLBACK OutAudioThread(LPVOID lpParameter);
static DWORD CALLBACK InAudioThread(LPVOID lpParameter);
static DWORD CALLBACK RecvThread(LPVOID lpParameter);
void InitWaveFormat();
void InitInWaveHdr();
void InitOutWaveHdr();
static bool IsPlay();
static bool IsMySelfAudio();
/************************************************************************/
/* In Audio Function */
/************************************************************************/
void InitWaveIn();
static void WaveInBuf();
/************************************************************************/
/* Out Audio Function */
/************************************************************************/
void InitWaveOut();
void TransLastError(DWORD ErrCode);
private:
static DWORD OutAudioThreadID;
static DWORD CurrentChannel;
static bool IsTimeOut;
static bool IsSpeakFinsh;
static queue<struct protocol> RecvQueue;
WAVEFORMATEX wfx;
static HWAVEIN hWaveIn;
static HWAVEOUT hWaveOut;
static WAVEHDR InWaveHdr;
static WAVEHDR OutWaveHdr;
static char HostIP[5][28];
static SOCKET sRecv;
static SOCKET sSend;
static SOCKET sServer;
static struct sockaddr_in sin_Recv;
static struct sockaddr_in sin_Send;
static struct sockaddr_in sin_server;
static struct protocol RecvData;
static struct protocol SendData;
HANDLE hOutAudio;
HANDLE hInAudio;
HANDLE hRecvThread;
};
class CAudioChat
{
public:
CAudioChat();
~CAudioChat();
/************************************************************************/
/* NetWork Public Function */
/************************************************************************/
static int CreateBroadSend();
static int CreateBroadRecv();
void CreateOutThread();
void CreateInThread();
static DWORD SendAudio();
static DWORD RecvAudio();
static void PlayAudio();
/************************************************************************/
/* Audio Function */
/************************************************************************/
static void BeginRecord(const int nTime=500);
static void waveOutProc(HWAVEOUT hwo,UINT uMsg,DWORD dwInstance,DWORD dwParam1,DWORD dwParam2);
private:
/************************************************************************/
/* NetWork Private Function */
/************************************************************************/
void InitSockData(void);
void GetHostIP();
int ConnectToServer(const char *Address="210.34.158.99",const int Port=SERVER_PORT);
void SendUserInfo(const char *name="NoName",const int priority=10);
/************************************************************************/
/* Audio Private Function */
/************************************************************************/
static DWORD CALLBACK OutAudioThread(LPVOID lpParameter);
static DWORD CALLBACK InAudioThread(LPVOID lpParameter);
static DWORD CALLBACK RecvThread(LPVOID lpParameter);
void InitWaveFormat();
void InitInWaveHdr();
void InitOutWaveHdr();
static bool IsPlay();
static bool IsMySelfAudio();
/************************************************************************/
/* In Audio Function */
/************************************************************************/
void InitWaveIn();
static void WaveInBuf();
/************************************************************************/
/* Out Audio Function */
/************************************************************************/
void InitWaveOut();
void TransLastError(DWORD ErrCode);
private:
static DWORD OutAudioThreadID;
static DWORD CurrentChannel;
static bool IsTimeOut;
static bool IsSpeakFinsh;
static queue<struct protocol> RecvQueue;
WAVEFORMATEX wfx;
static HWAVEIN hWaveIn;
static HWAVEOUT hWaveOut;
static WAVEHDR InWaveHdr;
static WAVEHDR OutWaveHdr;
static char HostIP[5][28];
static SOCKET sRecv;
static SOCKET sSend;
static SOCKET sServer;
static struct sockaddr_in sin_Recv;
static struct sockaddr_in sin_Send;
static struct sockaddr_in sin_server;
static struct protocol RecvData;
static struct protocol SendData;
HANDLE hOutAudio;
HANDLE hInAudio;
HANDLE hRecvThread;
};