#include "PlayerMgr.h"
#include <stdio.h>
#include <mmsystem.h>
#pragma comment( lib, "ws2_32.lib")
#pragma comment( lib, "winmm.lib" )
//放音设备句柄
HWAVEOUT g_hwo = NULL;
HWAVEIN g_hwi = NULL;
//放音音频头结构体
WAVEHDR g_whOut[8] = { 0 };
WAVEHDR g_whIn[8] = { 0 };
//放音缓冲区
BYTE g_byBufferOut[1024*1024] = { 0 };
BYTE g_byWavBuffer[8][64*1024] = { 0 };
//放音、接收索引
int g_nPlayIndex = 0;
int g_nUnitSize = 0;
int g_nRcvIndex = 0;
int g_nWavSize = 0;
int g_nWavTotal = 0;
WAVEFORMATEX g_objWavFormat = { 0 };
void CALLBACK _waveOutCallback( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 );
void CALLBACK _waveInCallback ( HWAVEIN hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 );
#pragma pack( 1 )
typedef struct _WaveFileHeader
{
char cChunkID[4]; // R I F F
int nChunkSize; // FileSize - 8 bytes
char cFormat[4]; // W A V E
char cSubChunk1ID[4]; // F M T
int nSubChunk1Size; // this struct size - 8 bytes
short sAudioFormat; // PCM
short sNumChannels; // numbers of channel
int nSampleRate; // Samples per second
int nBytesRate; // bytes per second
short sBlockAlign; // align of block
short sBitsPerSample; // bits per sample
char cSubChunk2ID[4]; // d a t a
int nSubChunk2Size;
}WaveFileHeader;
#pragma pack()
PlayerMgr* g_pPlayerMgr = NULL;
PlayerMgr::PlayerMgr( int nArgc, char** szArgv ) :
m_wPort( 0 ),
m_bQuit( FALSE ),
m_bServer( FALSE ),
m_bRecord( FALSE ),
m_hThreadPlay( NULL ),
m_hThreadClient( NULL ),
m_hThreadServer( NULL ),
m_hThreadWavPlay( NULL ),
m_socket( INVALID_SOCKET ),
m_hFileWave( INVALID_HANDLE_VALUE )
{
g_pPlayerMgr = this;
memset( m_szServerIP, 0, sizeof( m_szServerIP ));
WSADATA wsaData = { 0 };
if ( WSAStartup( 0x202, &wsaData ))
{
printf( "初始化网络失败!\n" );
}
else
{
strcpy( m_szServerIP, szArgv[2] );
m_wPort = atoi( szArgv[3] );
if ( 0 == stricmp( szArgv[1], "-s" ))
{
m_bServer = TRUE;
if ( 5 == nArgc && 0 == stricmp( szArgv[4], "-record" ))
{
m_bRecord = TRUE;
}
m_hThreadServer = CreateThread( NULL, 0, ServerThread, this, 0, NULL );
if ( NULL == m_hThreadServer )
{
printf( "网络线程启动失败!\n" );
}
}
else
{
m_hThreadClient = CreateThread( NULL, 0, ClientThread, this, 0, NULL );
if ( NULL == m_hThreadClient )
{
printf( "网络线程启动失败!\n" );
}
}
}
}
PlayerMgr::~PlayerMgr()
{
m_bQuit = TRUE;
while ( NULL != m_hThreadServer
|| NULL != m_hThreadClient
|| NULL != m_hThreadPlay
|| NULL != m_hThreadWavPlay )
{
Sleep( 10 );
}
if ( m_bRecord )
{
UninitAudio();
}
WSACleanup();
m_hThreadPlay = NULL;
m_hThreadClient = NULL;
m_hThreadServer = NULL;
m_hThreadWavPlay= NULL;
}
DWORD __stdcall PlayerMgr::ServerThread( LPVOID lpVoid )
{
printf( "服务线程启动成功!\n" );
PlayerMgr* pPlayerMgr = ( PlayerMgr* )lpVoid;
BOOL bResult = FALSE;
SOCKET sock = INVALID_SOCKET;
while ( !pPlayerMgr->m_bQuit )
{
if ( pPlayerMgr->InitSocket( sock ))
{
break;
}
if ( INVALID_SOCKET != sock )
{
shutdown( sock, SD_BOTH );
closesocket( sock );
sock = INVALID_SOCKET;
}
Sleep( 200 );
}
if ( pPlayerMgr->m_bRecord )
{
pPlayerMgr->InitWavein();
}
pPlayerMgr->StartListen( sock );
if ( INVALID_SOCKET != sock )
{
shutdown( sock, SD_BOTH );
closesocket( sock );
sock = INVALID_SOCKET;
}
CloseHandle( pPlayerMgr->m_hThreadServer );
pPlayerMgr->m_hThreadServer = NULL;
printf( "服务线程退出成功!\n" );
return 0;
}
DWORD __stdcall PlayerMgr::ClientThread( LPVOID lpVoid )
{
printf( "客户端线程启动成功!\n" );
PlayerMgr* pPlayerMgr = ( PlayerMgr* )lpVoid;
pPlayerMgr->m_hThreadWavPlay = CreateThread( NULL, 0, WavPlayThread, pPlayerMgr, 0, NULL );
g_nPlayIndex = 0;
g_nRcvIndex = 0;
while ( !pPlayerMgr->m_bQuit )
{
SOCKET sock = INVALID_SOCKET;
if ( FALSE == pPlayerMgr->InitSocket( sock ))
{
Sleep( 200 );
continue;
}
pPlayerMgr->RcvWavData( sock );
shutdown( sock, SD_BOTH );
closesocket( sock );
break;
}
CloseHandle( pPlayerMgr->m_hThreadClient );
pPlayerMgr->m_hThreadClient = NULL;
printf( "客户端线程退出成功!\n" );
return 0;
}
DWORD __stdcall PlayerMgr::WavPlayThread( LPVOID lpVoid )
{
printf( "放音线程启动成功!\n" );
PlayerMgr* pPlayerMgr = ( PlayerMgr* )lpVoid;
int nWavCur = 0;
int nCpyCur = 0;
while ( !pPlayerMgr->m_bQuit && pPlayerMgr->m_hThreadClient )
{
if ( g_nPlayIndex < g_nRcvIndex )
{
waveOutUnprepareHeader( g_hwo, &g_whOut[nWavCur%8], sizeof( WAVEHDR));
memcpy( g_byWavBuffer[nWavCur%8], g_byBufferOut + (nCpyCur%24) * g_nUnitSize, g_nUnitSize );
waveOutPrepareHeader( g_hwo, &g_whOut[nWavCur%8], sizeof( WAVEHDR));
waveOutWrite( g_hwo, &g_whOut[nWavCur%8], sizeof( WAVEHDR ));
++nWavCur;
++g_nPlayIndex;
++nCpyCur;
}
Sleep( 120 );
}
printf( "放音线程退出成功!\n" );
CloseHandle( pPlayerMgr->m_hThreadWavPlay );
pPlayerMgr->m_hThreadWavPlay = NULL;
return 0;
}
DWORD __stdcall PlayerMgr::RecordThread( LPVOID lpVoid )
{
printf( "录音发送线程启动成功!\n" );
PlayerMgr* pPlayerMgr = ( PlayerMgr* )lpVoid;
int nCpyCur = 0;
WaveFileHeader objWavFileHead = { 0 };
objWavFileHead.nBytesRate = g_objWavFormat.nAvgBytesPerSec;
objWavFileHead.sBlockAlign = g_objWavFormat.nBlockAlign;
objWavFileHead.sNumChannels = g_objWavFormat.nChannels;
objWavFileHead.nSampleRate = g_objWavFormat.nSamplesPerSec;
objWavFileHead.sBitsPerSample = g_objWavFormat.wBitsPerSample;
send( pPlayerMgr->m_socket, ( char* )&objWavFileHead, sizeof( WaveFileHeader ), 0 );
while ( !pPlayerMgr->m_bQuit )
{
fd_set fdSet = { 0 };
fdSet.fd_array[0] = pPlayerMgr->m_socket;
fdSet.fd_count = 1;
timeval tmVal = { 3, 0 };
int nRet = select( 1, NULL, &fdSet, NULL, &tmVal );
if ( SOCKET_ERROR == nRet )
{
break;
}
else if ( 0 == nRet )
{
Sleep( 200 );
continue;
}
if ( g_nPlayIndex < g_nRcvIndex )
{
if ( SOCKET_ERROR == send( pPlayerMgr->m_socket, ( char* )g_byBufferOut + (nCpyCur%24) * g_nUnitSize, g_nUnitSize, 0 ))
{
break;
}
++g_nPlayIndex;
++nCpyCur;
}
Sleep( 10 );
}
shutdown( pPlayerMgr->m_socket, SD_BOTH );
closesocket( pPlayerMgr->m_socket );
pPlayerMgr->m_socket = INVALID_SOCKET;
CloseHandle( pPlayerMgr->m_hThreadPlay );
pPlayerMgr->m_hThreadPlay = NULL;
printf( "录音发送线程退出成功!\n" );
return 0;
}
DWORD __stdcall PlayerMgr::PlayThread( LPVOID lpVoid )
{
printf( "音频读取线程启动成功!\n" );
PlayerMgr* pPlayerMgr = ( PlayerMgr* )lpVoid;
HANDLE hFile = CreateFile( pPlayerMgr->m_szServerIP, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
BOOL bOnce = FALSE;
if ( INVALID_HANDLE_VALUE != hFile )
{
DWORD dwRead = 0;
DWORD dwNeedRead = sizeof( WaveFileHeader );
while ( !pPlayerMgr->m_bQuit )
{
BYTE byBuffer[64*1024] = { 0 };
if ( ReadFile( hFile, byBuffer, dwNeedRead, &dwRead, NULL ) && 0 != dwRead )
{
if ( !bOnce )
{
bOnce = TRUE;
WaveFileHeader objWavFileHead = *( WaveFileHeader* )byBuffer;
dwNeedRead = objWavFileHead.nBytesRate / 8;
dwNeedRead -= ( dwNeedRead % objWavFileHead.sBlockAlign );
}
else
{
dwRead = 1000;
}
if ((int)dwRead != send( pPlayerMgr->m_socket, ( char* )byBuffer, dwRead, 0 ))
{
break;
}
}
else
{
break;
}
Sleep( 120 );
}
CloseHandle( hFile );
}