SoundIn.cpp
上传用户:onsales
上传日期:2010-01-31
资源大小:224k
文件大小:6k
源码类别:

网络编程

开发平台:

Visual C++

  1. // SoundIn.cpp: implementation of the CSoundIn class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "Speak.h"
  6. #include "SoundIn.h"
  7. #pragma comment(lib, "winmm")
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. UINT WaveInThreadProc(void * pParam);
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. CSoundIn::CSoundIn()
  18. {
  19. m_WaveInSampleRate = 11025;
  20. m_TerminateThread=FALSE;
  21. m_nBlock=1024;
  22. m_nBlockNum=2;
  23. m_nBits=8;
  24. m_nCurrent=0;
  25. m_WaveHeader=NULL;
  26. m_pInputBuffer=NULL;
  27. }
  28. CSoundIn::~CSoundIn()
  29. {
  30. if(m_WaveHeader!=NULL)
  31. free(m_WaveHeader);
  32. if(m_pInputBuffer!=NULL)
  33. free(m_pInputBuffer);
  34. }
  35. MMRESULT CSoundIn::OpenMic()
  36. {
  37. m_WaveHeader=(WAVEHDR*)malloc(m_nBlockNum*sizeof(WAVEHDR));
  38. int n=(int)m_nBits/8;
  39. m_pInputBuffer=(char*)malloc(n*m_nBlockNum*m_nBlock);
  40. m_cpSend->SetWaveFormat(1,m_WaveInSampleRate,m_nBits);
  41. m_cpSend->SetSrcSamples(m_nBlock,(unsigned char*)m_pInputBuffer);
  42. m_cpSend->Initialize();
  43. m_cpSend->PrepareSpace(TRUE);
  44. MMRESULT result;
  45.     result=waveInGetNumDevs(); 
  46. if (result == 0)
  47. {
  48.         AfxMessageBox("No Sound Device");
  49. return result;
  50. }
  51.     // test for Mic available   
  52.     result=waveInGetDevCaps (0, &m_WaveInDevCaps, sizeof(WAVEINCAPS));
  53.     if ( result!= MMSYSERR_NOERROR)
  54.     {
  55.        AfxMessageBox(_T("Cannot determine sound card capabilities !"));
  56.     }
  57. // The Sound Devive is OK now we can create an Event  and start the Thread
  58. m_WaveInEvent = CreateEvent(NULL,FALSE,FALSE,"WaveInThreadEvent");
  59. m_TerminateThread = FALSE;
  60. m_WaveInThread= AfxBeginThread(WaveInThreadProc,this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED,NULL);   
  61. m_WaveInThread->m_bAutoDelete = TRUE;
  62. m_WaveInThread->ResumeThread();
  63. // init format 
  64. WaveInitFormat(1/* mono*/,m_WaveInSampleRate /* khz */,m_nBits /* bits */); 
  65. // Open Input 
  66. result = waveInOpen( &m_WaveIn,0, &m_WaveFormat,(DWORD)m_WaveInEvent ,NULL ,CALLBACK_EVENT); 
  67. if ( result!= MMSYSERR_NOERROR)
  68. {
  69.         AfxMessageBox(_T("Cannot Open Sound Input Device!"));
  70.     return result;
  71. }
  72. for(int i=0;i<m_nBlockNum;i++){
  73. (*(m_WaveHeader+i)).lpData = (LPSTR)(m_pInputBuffer+i*m_nBlock*n);
  74. (*(m_WaveHeader+i)).dwBufferLength=m_nBlock*n;
  75. (*(m_WaveHeader+i)).dwFlags = 0;
  76. result = waveInPrepareHeader( m_WaveIn, m_WaveHeader+i, sizeof(WAVEHDR) ); 
  77. if ( (result!= MMSYSERR_NOERROR)||((*(m_WaveHeader+i)).dwFlags != WHDR_PREPARED))
  78. {
  79. // AfxMessageBox(_T("Cannot Prepare Header !"));
  80. return result;
  81. }
  82.     result = waveInAddBuffer( m_WaveIn,m_WaveHeader+i, sizeof(WAVEHDR));
  83. if  (result!= MMSYSERR_NOERROR) 
  84. {
  85. AfxMessageBox(_T("Cannot Add Buffer !"));
  86. return result;
  87. }
  88. }
  89.     // all is correct now we can start the process
  90.     result = waveInStart( m_WaveIn );
  91.     if  (result!= MMSYSERR_NOERROR) 
  92.     {
  93.         AfxMessageBox(_T("Cannot Start Wave In !"));
  94.     return result;
  95.     }
  96.     return result;
  97. }
  98. void CSoundIn::WaveInitFormat(WORD    nCh, // number of channels (mono, stereo)
  99.   DWORD   nSampleRate, // sample rate
  100.   WORD    BitsPerSample)
  101. {
  102. m_WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
  103. m_WaveFormat.nChannels = nCh;
  104. m_WaveFormat.nSamplesPerSec = nSampleRate;
  105. m_WaveFormat.nAvgBytesPerSec = nSampleRate * nCh * BitsPerSample/8;
  106. m_WaveFormat.nBlockAlign = m_WaveFormat.nChannels * BitsPerSample/8;
  107. m_WaveFormat.wBitsPerSample = BitsPerSample;
  108. m_WaveFormat.cbSize = 0;
  109. }
  110. void CSoundIn::AddBuffer()
  111. {
  112. MMRESULT result;
  113. int n=(int)m_nBits/8;
  114. result = waveInUnprepareHeader(m_WaveIn, m_WaveHeader+m_nCurrent, sizeof(WAVEHDR)); 
  115. if(result!= MMSYSERR_NOERROR) 
  116.     {
  117.            return;
  118. }
  119. //Here to call the data process procedue!
  120. if(m_bTest)
  121. m_sndOut->WriteData(m_pInputBuffer+m_nCurrent*m_nBlock*n,m_nBlock*n);
  122. else{
  123. m_cpSend->SetSrcSamples(m_nBlock,(unsigned char*)m_pInputBuffer+m_nCurrent*m_nBlock*n);
  124. m_cpSend->ConvertSend(m_sSend,m_addrTo);
  125. //int iError=sendto(m_sSend,m_pInputBuffer+m_nCurrent*m_nBlock*n,m_nBlock*n,0,(LPSOCKADDR)&m_addrTo,sizeof(m_addrTo));
  126. //if(iError==SOCKET_ERROR)
  127. // TRACE("Error In the sending!");
  128. }
  129.   (*(m_WaveHeader+m_nCurrent)).lpData = (LPSTR)(m_pInputBuffer+m_nCurrent*m_nBlock*n);
  130.     (*(m_WaveHeader+m_nCurrent)).dwBufferLength =m_nBlock*n;
  131. (*(m_WaveHeader+m_nCurrent)).dwFlags = 0;
  132.     result = waveInPrepareHeader( m_WaveIn, m_WaveHeader+m_nCurrent, sizeof(WAVEHDR) ); 
  133. if ( (result!= MMSYSERR_NOERROR)||((*(m_WaveHeader+m_nCurrent)).dwFlags != WHDR_PREPARED) )
  134.         AfxMessageBox(_T("Cannot Prepare Header !"));
  135.     result = waveInAddBuffer( m_WaveIn, m_WaveHeader+m_nCurrent, sizeof(WAVEHDR) );
  136.     if (result!= MMSYSERR_NOERROR) 
  137.         AfxMessageBox(_T("Cannot Add Buffer !"));
  138.     result = waveInStart( m_WaveIn );
  139.     if  (result!= MMSYSERR_NOERROR) 
  140.         AfxMessageBox(_T("Cannot Start Wave In !"));
  141. m_nCurrent++;
  142. m_nCurrent%=m_nBlockNum;
  143. }
  144. void CSoundIn::CloseMic()
  145. {
  146. m_TerminateThread = TRUE;
  147.     if (m_WaveInEvent )
  148. SetEvent(m_WaveInEvent);
  149.     Sleep(50);  // wait for the thread to terminate
  150. if (m_WaveIn) 
  151. {
  152. waveInReset(m_WaveIn);
  153. waveInStop(m_WaveIn);
  154. waveInClose(m_WaveIn);
  155. }
  156. }
  157. void CSoundIn::StopMic()
  158. {
  159. waveInStop(m_WaveIn);
  160. waveInReset(m_WaveIn);
  161. }
  162. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  163. //    Glogal Thread procedure for the CSoundIn class
  164. //    It cannot be included inside the Class
  165. //   
  166. // The LPARAM is the Class pointer (this) it can be the base class CSoundIn ptr or a derived new class
  167. // The value of this parametre can change according the Topmost class of the process 
  168. /////////////////////////////////////////////////////////////////////////////////////////////////////////////
  169. #define PT_S ((CSoundIn*)pParam) 
  170. UINT WaveInThreadProc(void * pParam)
  171. {
  172.    UINT result;
  173.    UINT FirstPass = TRUE;
  174. if ( FirstPass)
  175. result = WaitForSingleObject(((CSoundIn*)pParam)->m_WaveInEvent,INFINITE);
  176. FirstPass = FALSE;
  177.     
  178. while (!((CSoundIn*)pParam)->m_TerminateThread)
  179. {
  180. result = WaitForSingleObject(PT_S->m_WaveInEvent,INFINITE);
  181. if ((result == WAIT_OBJECT_0)&&(!PT_S->m_TerminateThread ))
  182. {
  183. PT_S->AddBuffer();      
  184. }
  185. else
  186. return 0;  
  187. }
  188.     return 0;
  189. }