📄 myvoipctl.cpp
字号:
void CMyvoipCtrl::AboutBox()
{
CDialog dlgAbout(IDD_ABOUTBOX_MYVOIP);
dlgAbout.DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CMyvoipCtrl message handlers
HRESULT CMyvoipCtrl::CreateOutputBuffer()
{
HRESULT hr;
WAVEFORMATEX wfxInput;
// This sample works by creating notification events which
// are signaled when the capture buffer reachs specific offsets
// WinMain() waits for the associated event to be signaled, and
// when it is, it calls HandleNotifications() which copy the
// data from the capture buffer into the output buffer
ZeroMemory( &wfxInput, sizeof(wfxInput) );
g_pDSBCapture->GetFormat( &wfxInput, sizeof(wfxInput), NULL );
// Create the direct sound buffer using the same format as the
// capture buffer.
DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize = sizeof(DSBUFFERDESC);
dsbd.dwFlags = DSBCAPS_GLOBALFOCUS;
dsbd.dwBufferBytes = g_dwOutputBufferSize;
dsbd.guid3DAlgorithm = GUID_NULL;
dsbd.lpwfxFormat = &wfxInput;
// Create the DirectSound buffer
if( FAILED( hr = g_pDS->CreateSoundBuffer( &dsbd, &g_pDSBOutput, NULL ) ) )
return DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );
// Create a notification event, for when the sound stops playing
if( FAILED( hr = g_pDSBCapture->QueryInterface( IID_IDirectSoundNotify,
(VOID**)&g_pDSNotify ) ) )
return DXTRACE_ERR( TEXT("QueryInterface"), hr );
// Setup the notification positions
for( INT i = 0; i < NUM_PLAY_NOTIFICATIONS; i++ )
{
g_aPosNotify[i].dwOffset = (g_dwNotifySize * i) + g_dwNotifySize - 1;
g_aPosNotify[i].hEventNotify = g_hNotificationEvent;
}
// Tell DirectSound when to notify us. the notification will come in the from
// of signaled events that are handled in WinMain()
if( FAILED( hr = g_pDSNotify->SetNotificationPositions( NUM_PLAY_NOTIFICATIONS,
g_aPosNotify ) ) )
return DXTRACE_ERR( TEXT("SetNotificationPositions"), hr );
return S_OK;
}
HRESULT CMyvoipCtrl::FreeDirectSound()
{
SAFE_RELEASE( g_pDSNotify );
SAFE_RELEASE( g_pDSBPrimary );
SAFE_RELEASE( g_pDSBOutput );
SAFE_RELEASE( g_pDSBCapture );
SAFE_RELEASE( g_pDSCapture );
SAFE_RELEASE( g_pDS );
return S_OK;
}
HRESULT CMyvoipCtrl::HandleNotification()
{
HRESULT hr;
VOID* pDSCaptureLockedBuffer = NULL;
DWORD dwDSCaptureLockedBufferSize;
// Lock the capture buffer down
if( FAILED( hr = g_pDSBCapture->Lock( g_dwNextCaptureOffset, g_dwNotifySize,
&pDSCaptureLockedBuffer,
&dwDSCaptureLockedBufferSize,
NULL, NULL, 0L ) ) )
return DXTRACE_ERR( TEXT("Lock"), hr );
voicepacket voice;
memcpy(voice.clientid,destID,20);
//memset(voice->buf,0,sizeof(buf));
memcpy(voice.buff,pDSCaptureLockedBuffer,dwDSCaptureLockedBufferSize);
//These should be equal
int nResult;
nResult=Sock.SendTo(&voice,dwDSCaptureLockedBufferSize+20,1720,destIP);
// timer++;
// Unlock the capture buffer
g_pDSBCapture->Unlock( pDSCaptureLockedBuffer, dwDSCaptureLockedBufferSize,
NULL, 0 );
// Move the capture offset along
g_dwNextCaptureOffset += dwDSCaptureLockedBufferSize;
g_dwNextCaptureOffset %= g_dwCaptureBufferSize; // Circular buffer
return S_OK;
}
//////////////////
GUID devGuid = GUID_NULL;
BOOL CALLBACK DSEnumProc(LPGUID lpGUID,
LPCTSTR lpszDesc,
LPCTSTR lpszDrvName,
LPVOID lpContext )
{
LPGUID lpTemp = NULL;
if ( lpGUID != NULL )
{
if (( lpTemp = (LPGUID)malloc( sizeof(GUID))) == NULL )
return( TRUE );
memcpy( lpTemp, lpGUID, sizeof(GUID));
if(*lpGUID != GUID_NULL)
{
//AfxMessageBox("选中");
devGuid = *lpGUID;
return FALSE;
}
}
return( TRUE );
}
///////////////////////
HRESULT CMyvoipCtrl::InitDirectSound()
{
HRESULT hr;
DSBUFFERDESC dsbdesc;
g_hNotificationEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
ZeroMemory( &g_aPosNotify, sizeof(DSBPOSITIONNOTIFY) *
(NUM_PLAY_NOTIFICATIONS) );
g_dwOutputBufferSize = 0;
g_dwCaptureBufferSize = 0;
g_dwNotifySize = 0;
g_dwNextOutputOffset = 0;
if FAILED(DirectSoundEnumerate((LPDSENUMCALLBACK)DSEnumProc,NULL))
{
return( TRUE );
}
if (devGuid == GUID_NULL)
{
AfxMessageBox("声卡驱动须升级&&声卡未驱动");
return S_OK;
}
// Create IDirectSound using the preferred sound device
if( FAILED( hr = DirectSoundCreate( &devGuid, &g_pDS, NULL ) ) )
return DXTRACE_ERR( TEXT("DirectSoundCreate"), hr );
// Set coop level to DSSCL_PRIORITY
if( FAILED( hr = g_pDS->SetCooperativeLevel(hWnd, DSSCL_PRIORITY ) ) )
return DXTRACE_ERR( TEXT("SetCooperativeLevel"), hr );
// Obtain primary buffer
ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
if( FAILED( hr = g_pDS->CreateSoundBuffer( &dsbdesc, &g_pDSBPrimary, NULL ) ) )
return DXTRACE_ERR( TEXT("CreateSoundBuffer"), hr );
// Create IDirectSoundCapture using the preferred capture device
if( FAILED( hr = DirectSoundCaptureCreate( NULL, &g_pDSCapture, NULL ) ) )
return DXTRACE_ERR( TEXT("DirectSoundCaptureCreate"), hr );
return S_OK;
}
HRESULT CMyvoipCtrl::OnFormatsOK()
{
HRESULT hr;
WAVEFORMATEX wfxInput;
WAVEFORMATEX wfxOutput;
ZeroMemory( &wfxInput, sizeof(wfxInput) );
wfxInput.wFormatTag = WAVE_FORMAT_PCM;
wfxInput.nSamplesPerSec =8000;
wfxInput.wBitsPerSample = 8;
wfxInput.nChannels=2;
wfxInput.nBlockAlign = wfxInput.nChannels * ( wfxInput.wBitsPerSample / 8 );
wfxInput.nAvgBytesPerSec = wfxInput.nBlockAlign * wfxInput.nSamplesPerSec;
ZeroMemory( &wfxOutput, sizeof(wfxOutput) );
wfxOutput.wFormatTag = WAVE_FORMAT_PCM;
wfxOutput.nChannels=2;
wfxOutput.nSamplesPerSec =8000;
wfxOutput.wBitsPerSample = 8;
wfxOutput.nBlockAlign =wfxOutput.nChannels * ( wfxOutput.wBitsPerSample / 8 );
wfxOutput.nAvgBytesPerSec =wfxOutput.nBlockAlign * wfxOutput.nSamplesPerSec;
if( FAILED( hr = SetBufferFormats( &wfxInput, &wfxOutput ) ) )
return DXTRACE_ERR( TEXT("SetBufferFormats"), hr );
return S_OK;
}
HRESULT CMyvoipCtrl::RestoreBuffer(LPDIRECTSOUNDBUFFER pDSBuffer, BOOL *pbRestored)
{
HRESULT hr;
if( pbRestored != NULL )
*pbRestored = FALSE;
if( NULL == pDSBuffer )
return S_FALSE;
DWORD dwStatus;
if( FAILED( hr = pDSBuffer->GetStatus( &dwStatus ) ) )
return DXTRACE_ERR( TEXT("GetStatus"), hr );
if( dwStatus & DSBSTATUS_BUFFERLOST )
{
// Since the app could have just been activated, then
// DirectSound may not be giving us control yet, so
// the restoring the buffer may fail.
// If it does, sleep until DirectSound gives us control.
do
{
hr = pDSBuffer->Restore();
if( hr == DSERR_BUFFERLOST )
Sleep( 10 );
}
while( hr = pDSBuffer->Restore() );
if( pbRestored != NULL )
*pbRestored = TRUE;
return S_OK;
}
else
{
return S_FALSE;
}
}
HRESULT CMyvoipCtrl::SetBufferFormats(WAVEFORMATEX *pwfxInput, WAVEFORMATEX *pwfxOutput)
{
HRESULT hr;
// Set the format of the primary buffer
// to the format of the output buffer
if( FAILED( hr = g_pDSBPrimary->SetFormat( pwfxOutput ) ) )
return DXTRACE_ERR( TEXT("SetFormat"), hr );
// Set the notification size
g_dwNotifySize = MAX(4096, pwfxInput->nAvgBytesPerSec / 8 );
g_dwNotifySize -= g_dwNotifySize % pwfxInput->nBlockAlign;
// Set the buffer sizes
g_dwOutputBufferSize=NUM_BUFFERS * g_dwNotifySize / 2;
g_dwCaptureBufferSize=g_dwNotifySize * NUM_BUFFERS;
SAFE_RELEASE( g_pDSBCapture );
// Create the capture buffer
DSCBUFFERDESC dscbd;
ZeroMemory( &dscbd, sizeof(dscbd) );
dscbd.dwSize = sizeof(dscbd);
dscbd.dwBufferBytes = g_dwCaptureBufferSize;
dscbd.lpwfxFormat = pwfxInput; // Set the format during creatation
if( FAILED( hr = g_pDSCapture->CreateCaptureBuffer( &dscbd,
&g_pDSBCapture,
NULL ) ) )
return DXTRACE_ERR( TEXT("CreateCaptureBuffer"), hr );
return S_OK;
}
HRESULT CMyvoipCtrl::StartBuffers()
{
WAVEFORMATEX wfxOutput;
VOID* pDSLockedBuffer = NULL;
DWORD dwDSLockedBufferSize;
HRESULT hr;
// Restore lost buffers
if( FAILED( hr = RestoreBuffer( g_pDSBOutput, NULL ) ) )
return DXTRACE_ERR( TEXT("RestoreBuffer"), hr );
// Find out where the capture buffer is right now, then write data
// some extra amount forward to make sure we're ahead of the write cursor
g_pDSBCapture->GetCurrentPosition( &g_dwNextCaptureOffset, NULL );
g_dwNextCaptureOffset -= g_dwNextCaptureOffset % g_dwNotifySize;
g_dwNextOutputOffset = g_dwNextCaptureOffset + ( 2 * g_dwNotifySize );
g_dwNextOutputOffset %= g_dwOutputBufferSize; // Circular buffer
// Tell the capture buffer to start recording
g_pDSBCapture->Start( DSCBSTART_LOOPING );
// Rewind the output buffer, fill it with silence, and play it
g_pDSBOutput->SetCurrentPosition( g_dwNextCaptureOffset );
// Save the format of the capture buffer in g_pCaptureWaveFormat
ZeroMemory( &g_wfxCaptureWaveFormat, sizeof(WAVEFORMATEX) );
g_pDSBCapture->GetFormat( &g_wfxCaptureWaveFormat, sizeof(WAVEFORMATEX), NULL );
// Get the format of the output buffer
ZeroMemory( &wfxOutput, sizeof(wfxOutput) );
g_pDSBOutput->GetFormat( &wfxOutput, sizeof(wfxOutput), NULL );
// Fill the output buffer with silence at first
// As capture data arrives, HandleNotifications() will fill
// the output buffer with wave data.
if( FAILED( hr = g_pDSBOutput->Lock( 0, g_dwOutputBufferSize,
&pDSLockedBuffer, &dwDSLockedBufferSize,
NULL, NULL, 0 ) ) )
return DXTRACE_ERR( TEXT("Lock"), hr );
FillMemory( (BYTE*) pDSLockedBuffer, dwDSLockedBufferSize,
(BYTE)( wfxOutput.wBitsPerSample == 8 ? 128 : 0 ) );
g_pDSBOutput->Unlock( pDSLockedBuffer, dwDSLockedBufferSize, NULL, NULL );
// Play the output buffer
g_pDSBOutput->Play( 0, 0, DSBPLAY_LOOPING );
return S_OK;
}
// initialize socket
void CMyvoipCtrl::InitSock()
{
int i;
if((i=Sock.Create(1720,SOCK_DGRAM,0))==0)
{
int re=GetLastError();
}
if(WSAAsyncSelect(Sock.m_hSocket,this->m_hWnd,UM_RECEIVERTP,FD_READ)==SOCKET_ERROR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -