www.gusucode.com > 一些VC++网络编程实例源代码-源码程序 > 一些VC++网络编程实例源代码-源码程序\code\第九章\Phone\SoundIn.cpp
//Download by http://www.NewXing.com // SoundIn.cpp: implementation of the CSoundIn class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Phone.h" #include "SoundIn.h" #pragma comment(lib, "winmm") #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif UINT WaveInThreadProc(void * pParam); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CSoundIn::CSoundIn() { m_WaveInSampleRate = 11025; m_TerminateThread=FALSE; m_nBlock=1024; m_nBlockNum=2; m_nBits=8; m_nCurrent=0; m_WaveHeader=NULL; m_pInputBuffer=NULL; } CSoundIn::~CSoundIn() { if(m_WaveHeader!=NULL) free(m_WaveHeader); if(m_pInputBuffer!=NULL) free(m_pInputBuffer); } MMRESULT CSoundIn::OpenMic() { m_WaveHeader=(WAVEHDR*)malloc(m_nBlockNum*sizeof(WAVEHDR)); int n=(int)m_nBits/8; m_pInputBuffer=(char*)malloc(n*m_nBlockNum*m_nBlock); m_cpSend->SetWaveFormat(1,m_WaveInSampleRate,m_nBits); m_cpSend->SetSrcSamples(m_nBlock,(unsigned char*)m_pInputBuffer); m_cpSend->Initialize(); m_cpSend->PrepareSpace(TRUE); MMRESULT result; result=waveInGetNumDevs(); if (result == 0) { AfxMessageBox("No Sound Device"); return result; } // test for Mic available result=waveInGetDevCaps (0, &m_WaveInDevCaps, sizeof(WAVEINCAPS)); if ( result!= MMSYSERR_NOERROR) { AfxMessageBox(_T("Cannot determine sound card capabilities !")); } // The Sound Devive is OK now we can create an Event and start the Thread m_WaveInEvent = CreateEvent(NULL,FALSE,FALSE,"WaveInThreadEvent"); m_TerminateThread = FALSE; m_WaveInThread= AfxBeginThread(WaveInThreadProc,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL); m_WaveInThread->m_bAutoDelete = TRUE; m_WaveInThread->ResumeThread(); // init format WaveInitFormat(1/* mono*/,m_WaveInSampleRate /* khz */,m_nBits /* bits */); // Open Input result = waveInOpen( &m_WaveIn,0, &m_WaveFormat,(DWORD)m_WaveInEvent ,NULL ,CALLBACK_EVENT); if ( result!= MMSYSERR_NOERROR) { AfxMessageBox(_T("Cannot Open Sound Input Device!")); return result; } for(int i=0;i<m_nBlockNum;i++){ (*(m_WaveHeader+i)).lpData = (LPSTR)(m_pInputBuffer+i*m_nBlock*n); (*(m_WaveHeader+i)).dwBufferLength=m_nBlock*n; (*(m_WaveHeader+i)).dwFlags = 0; result = waveInPrepareHeader( m_WaveIn, m_WaveHeader+i, sizeof(WAVEHDR) ); if ( (result!= MMSYSERR_NOERROR)||((*(m_WaveHeader+i)).dwFlags != WHDR_PREPARED)) { // AfxMessageBox(_T("Cannot Prepare Header !")); return result; } result = waveInAddBuffer( m_WaveIn,m_WaveHeader+i, sizeof(WAVEHDR)); if (result!= MMSYSERR_NOERROR) { AfxMessageBox(_T("Cannot Add Buffer !")); return result; } } // all is correct now we can start the process result = waveInStart( m_WaveIn ); if (result!= MMSYSERR_NOERROR) { AfxMessageBox(_T("Cannot Start Wave In !")); return result; } return result; } void CSoundIn::WaveInitFormat(WORD nCh, // number of channels (mono, stereo) DWORD nSampleRate, // sample rate WORD BitsPerSample) { m_WaveFormat.wFormatTag = WAVE_FORMAT_PCM; m_WaveFormat.nChannels = nCh; m_WaveFormat.nSamplesPerSec = nSampleRate; m_WaveFormat.nAvgBytesPerSec = nSampleRate * nCh * BitsPerSample/8; m_WaveFormat.nBlockAlign = m_WaveFormat.nChannels * BitsPerSample/8; m_WaveFormat.wBitsPerSample = BitsPerSample; m_WaveFormat.cbSize = 0; } void CSoundIn::AddBuffer() { MMRESULT result; int n=(int)m_nBits/8; result = waveInUnprepareHeader(m_WaveIn, m_WaveHeader+m_nCurrent, sizeof(WAVEHDR)); if(result!= MMSYSERR_NOERROR) { return; } //Here to call the data process procedue! if(m_bTest) m_sndOut->WriteData(m_pInputBuffer+m_nCurrent*m_nBlock*n,m_nBlock*n); else{ m_cpSend->SetSrcSamples(m_nBlock,(unsigned char*)m_pInputBuffer+m_nCurrent*m_nBlock*n); m_cpSend->ConvertSend(m_sSend,m_addrTo); //int iError=sendto(m_sSend,m_pInputBuffer+m_nCurrent*m_nBlock*n,m_nBlock*n,0,(LPSOCKADDR)&m_addrTo,sizeof(m_addrTo)); //if(iError==SOCKET_ERROR) // TRACE("Error In the sending!"); } (*(m_WaveHeader+m_nCurrent)).lpData = (LPSTR)(m_pInputBuffer+m_nCurrent*m_nBlock*n); (*(m_WaveHeader+m_nCurrent)).dwBufferLength =m_nBlock*n; (*(m_WaveHeader+m_nCurrent)).dwFlags = 0; result = waveInPrepareHeader( m_WaveIn, m_WaveHeader+m_nCurrent, sizeof(WAVEHDR) ); if ( (result!= MMSYSERR_NOERROR)||((*(m_WaveHeader+m_nCurrent)).dwFlags != WHDR_PREPARED) ) AfxMessageBox(_T("Cannot Prepare Header !")); result = waveInAddBuffer( m_WaveIn, m_WaveHeader+m_nCurrent, sizeof(WAVEHDR) ); if (result!= MMSYSERR_NOERROR) AfxMessageBox(_T("Cannot Add Buffer !")); result = waveInStart( m_WaveIn ); if (result!= MMSYSERR_NOERROR) AfxMessageBox(_T("Cannot Start Wave In !")); m_nCurrent++; m_nCurrent%=m_nBlockNum; } void CSoundIn::CloseMic() { m_TerminateThread = TRUE; if (m_WaveInEvent ) SetEvent(m_WaveInEvent); Sleep(50); // wait for the thread to terminate if (m_WaveIn) { waveInReset(m_WaveIn); waveInStop(m_WaveIn); waveInClose(m_WaveIn); } } void CSoundIn::StopMic() { waveInStop(m_WaveIn); waveInReset(m_WaveIn); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // Glogal Thread procedure for the CSoundIn class // It cannot be included inside the Class // // The LPARAM is the Class pointer (this) it can be the base class CSoundIn ptr or a derived new class // The value of this parametre can change according the Topmost class of the process ///////////////////////////////////////////////////////////////////////////////////////////////////////////// #define PT_S ((CSoundIn*)pParam) UINT WaveInThreadProc(void * pParam) { UINT result; UINT FirstPass = TRUE; if ( FirstPass) result = WaitForSingleObject(((CSoundIn*)pParam)->m_WaveInEvent,INFINITE); FirstPass = FALSE; while (!((CSoundIn*)pParam)->m_TerminateThread) { result = WaitForSingleObject(PT_S->m_WaveInEvent,INFINITE); if ((result == WAIT_OBJECT_0)&&(!PT_S->m_TerminateThread )) { PT_S->AddBuffer(); } else return 0; } return 0; }