SoundIn.cpp
上传用户:popouu88
上传日期:2013-02-11
资源大小:2894k
文件大小:5k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. // SoundIn.cpp: implementation of the CSoundIn class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "../../stdafx.h"
  5. #include "SoundIn.h"
  6. #ifdef _DEBUG
  7. #undef THIS_FILE
  8. static char THIS_FILE[]=__FILE__;
  9. #define new DEBUG_NEW
  10. #endif
  11. #pragma comment( lib , "winmm.lib" )
  12. //声音队列
  13. #define SEQUENCE_NUM   20
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. CSoundIn::CSoundIn()
  18. {
  19. this->m_hRecord = NULL;
  20. this->m_bRecord = false;
  21. this->sequenceNum = 0;
  22. //采集的图像格式
  23. this->SetWaveFormat( 1 , 8000 , 16 );
  24.     
  25. this->OnSound = NULL;
  26. this->pContext = NULL;
  27. this->encode = new CG729aCompress ( ); // new CGsmCompress( ); // new CG729aCompress ( );
  28. }
  29. CSoundIn::~CSoundIn( )
  30. {
  31. this->Stop( );
  32. delete this->encode;
  33. }
  34. void CSoundIn::SetWaveFormat( int channels /*1*/, long samplerate /*8000*/, int bitspersample/*16*/ )
  35. {
  36. memset(&this->wavFormat , 0 , sizeof( this->wavFormat ) );
  37. this->wavFormat.cbSize = 0;
  38. this->wavFormat.wFormatTag = WAVE_FORMAT_PCM; // pcm
  39. this->wavFormat.nChannels = channels; // mono
  40. this->wavFormat.nSamplesPerSec = samplerate; // 8000 kHz
  41. this->wavFormat.wBitsPerSample = bitspersample; // 16 bit
  42. this->wavFormat.nBlockAlign = this->wavFormat.nChannels * this->wavFormat.wBitsPerSample / 8;
  43. this->wavFormat.nAvgBytesPerSec = this->wavFormat.nSamplesPerSec * this->wavFormat.nBlockAlign;
  44. }
  45. WAVEFORMATEX * CSoundIn::GetFormat( int * size )
  46. {
  47. if( size )
  48. * size = sizeof( this->wavFormat );
  49. return &this->wavFormat;
  50. }
  51. void CSoundIn::SetCompress( int mode )
  52. {
  53. if(  this->encode )
  54. {
  55. if( this->encode->GetType( ) != mode )
  56. {
  57. CCompress * p = this->encode;
  58. if( mode == CCompress::GSM610 )
  59. this->encode = new CGsmCompress( );
  60. else if( mode == CCompress::G729a )
  61. this->encode = new CG729aCompress( );
  62. else
  63. this->encode = NULL;
  64. delete p;
  65. }
  66. }
  67. else if( mode == CCompress::GSM610 )
  68. this->encode = new CGsmCompress( );
  69. else if( mode == CCompress::G729a )
  70. this->encode = new CG729aCompress( );
  71. }
  72. bool CSoundIn::Start( void ( * OnSound )( void * pContext , char * buffer , int size ) , void * pContext )
  73. {
  74. if( this->m_bRecord )
  75. return true;
  76. if( ! OnSound )
  77. return false;
  78. this->sequenceNum = 0;
  79. this->OnSound = OnSound;
  80. this->pContext = pContext;
  81. if( ! this->m_hRecord )
  82. {
  83. MMRESULT mmReturn = ::waveInOpen( &this->m_hRecord , WAVE_MAPPER , &this->wavFormat , ( DWORD )waveInProc , ( DWORD )this , CALLBACK_FUNCTION );
  84. if( mmReturn != MMSYSERR_NOERROR )
  85. {
  86. this->Stop( ); return false;
  87. }
  88. for( int i = 0; i < SEQUENCE_NUM ; i ++ )
  89. {
  90. WAVEHDR * pHdr = new WAVEHDR;
  91. memset( pHdr , 0 , sizeof( WAVEHDR ) );
  92. pHdr->lpData = new char[ SIZE_AUDIO_FRAME ];
  93. pHdr->dwBufferLength = SIZE_AUDIO_FRAME;
  94. ::waveInPrepareHeader( this->m_hRecord , pHdr ,sizeof( WAVEHDR ) );
  95. ::waveInAddBuffer( this->m_hRecord , pHdr , sizeof( WAVEHDR ) );
  96. }
  97. this->m_bRecord = true;
  98. this->sequenceNum = SEQUENCE_NUM;
  99. mmReturn = ::waveInStart( this->m_hRecord );
  100. if( mmReturn != MMSYSERR_NOERROR )
  101. {
  102. this->Stop( ); return false;
  103. }
  104. return true;
  105. }
  106. return false;
  107. }
  108. void CSoundIn::Stop( void )
  109. {
  110. CWaitCursor cursor;
  111. if( this->m_bRecord )
  112. {
  113. this->m_bRecord = false;
  114. while( this->sequenceNum > 0 ) 
  115. ::Sleep( 100 );
  116. ::waveInReset( this->m_hRecord );
  117. ::waveInStop( this->m_hRecord );
  118. ::waveInClose( this->m_hRecord );
  119. this->m_hRecord = NULL;
  120. }
  121. }
  122. bool CSoundIn::Filter( char * buffer , int size )
  123. {
  124. return true;
  125. }
  126. void CALLBACK CSoundIn::waveInProc( HWAVEIN hwi , UINT uMsg , DWORD dwInstance , DWORD dwParam1 ,DWORD dwParam2 )
  127. {
  128. CSoundIn * pThis = ( CSoundIn * )dwInstance;
  129. if( uMsg == WIM_DATA )
  130. {
  131. WAVEHDR * pHdr = ( WAVEHDR * )dwParam1;
  132. MMRESULT mmReturn = ::waveInUnprepareHeader( hwi , pHdr , sizeof( WAVEHDR ) );
  133. if( mmReturn != MMSYSERR_NOERROR )
  134. return ;
  135. if( pThis->m_bRecord )
  136. {
  137. if( pThis->OnSound && pThis->Filter( pHdr->lpData , pHdr->dwBufferLength ) )
  138. {
  139. int size = pHdr->dwBufferLength;
  140. char * buf = pHdr->lpData;
  141. if( pThis->encode )
  142. buf = pThis->encode->Compress( pHdr->lpData , &size );
  143. pThis->OnSound( pThis->pContext , buf , size );
  144. }
  145. mmReturn = ::waveInPrepareHeader( hwi , pHdr , sizeof( WAVEHDR ) );
  146. if( mmReturn == MMSYSERR_NOERROR )
  147. {
  148. mmReturn = ::waveInAddBuffer( hwi , pHdr , sizeof( WAVEHDR ) );
  149. if( mmReturn == MMSYSERR_NOERROR )
  150. return;
  151. }
  152. }
  153. delete [ ]pHdr->lpData;
  154. delete [ ]pHdr;
  155. pThis->sequenceNum --;
  156. }
  157. }