SoundIn.cpp
上传用户:zjb_0001
上传日期:2007-01-11
资源大小:154k
文件大小:5k
源码类别:

Audio

开发平台:

Visual C++

  1. // SoundIn.cpp: implementation of the CSoundIn class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "SoundIn.h"
  6. // include callback class
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. //////////////////////////////////////////////////////////////////////
  13. // Construction/Destruction
  14. //////////////////////////////////////////////////////////////////////
  15. IMPLEMENT_DYNCREATE(CSoundIn, CWinThread)
  16. CSoundIn::CSoundIn()
  17. {
  18. m_QueuedBuffers = 0;
  19. m_hRecord = NULL;
  20. m_bRecording = false;
  21. DataFromSoundIn = NULL;
  22. m_pOwner = NULL;
  23. CreateThread();
  24. m_bAutoDelete = false;
  25. }
  26. CSoundIn::~CSoundIn()
  27. {
  28. if(m_bRecording)
  29. Stop();
  30. ::PostQuitMessage(0);
  31. }
  32. BOOL CSoundIn::InitInstance()
  33. {
  34. m_ThreadID = ::GetCurrentThreadId();
  35. return TRUE;
  36. }
  37. BEGIN_MESSAGE_MAP(CSoundIn, CWinThread)
  38. //{{AFX_MSG_MAP(CSoundIn)
  39. // NOTE - the ClassWizard will add and remove mapping macros here.
  40. //}}AFX_MSG_MAP
  41. ON_THREAD_MESSAGE(MM_WIM_DATA, OnMM_WIM_DATA)
  42. END_MESSAGE_MAP()
  43. bool CSoundIn::Start(WAVEFORMATEX* format)
  44. {
  45. MMRESULT mmReturn = 0;
  46. if(m_bRecording || DataFromSoundIn == NULL || m_pOwner == NULL)
  47. {
  48. // already recording!
  49. return FALSE;
  50. }
  51. else
  52. {
  53. if(format != NULL)
  54. m_Format = *format;
  55. // open wavein device
  56. mmReturn = ::waveInOpen( &m_hRecord, WAVE_MAPPER, &m_Format, m_ThreadID, NULL, CALLBACK_THREAD);
  57. if(mmReturn)
  58. {
  59. waveInErrorMsg(mmReturn, "in Start()");
  60. return FALSE;
  61. }
  62. else
  63. {
  64. // make several input buffers and add them to the input queue
  65. for(int i=0; i<3; i++)
  66. {
  67. AddInputBufferToQueue();
  68. }
  69. // start recording
  70. mmReturn = ::waveInStart(m_hRecord);
  71. if(mmReturn )
  72. {
  73. waveInErrorMsg(mmReturn, "in Start()");
  74. return FALSE;
  75. }
  76. m_bRecording = true;
  77. }
  78. }
  79. return TRUE;
  80. }
  81. void CSoundIn::Stop()
  82. {
  83. MMRESULT mmReturn = MMSYSERR_NOERROR;
  84. if(!m_bRecording)
  85. {
  86. return;
  87. }
  88. else
  89. {
  90. mmReturn = ::waveInReset(m_hRecord);
  91. if(mmReturn)
  92. {
  93. waveInErrorMsg(mmReturn, "in Stop()");
  94. return;
  95. }
  96. else
  97. {
  98. m_bRecording = FALSE;
  99. Sleep(500);
  100. mmReturn = ::waveInClose(m_hRecord);
  101. if(mmReturn) waveInErrorMsg(mmReturn, "in Stop()");
  102. }
  103. if(m_QueuedBuffers != 0) ErrorMsg("Still %d buffers in waveIn queue!", m_QueuedBuffers);
  104. }
  105. }
  106. void CSoundIn::OnMM_WIM_DATA(UINT parm1, LONG parm2)
  107. {
  108. MMRESULT mmReturn = 0;
  109. LPWAVEHDR pHdr = (LPWAVEHDR) parm2;
  110. mmReturn = ::waveInUnprepareHeader(m_hRecord, pHdr, sizeof(WAVEHDR));
  111. if(mmReturn)
  112. {
  113. waveInErrorMsg(mmReturn, "in OnWIM_DATA()");
  114. return;
  115. }
  116. TRACE("WIM_DATA %4dn", pHdr->dwBytesRecorded);
  117. if(m_bRecording)
  118. {
  119. CBuffer buf(pHdr->lpData, pHdr->dwBufferLength);
  120. // virtual processing function supplyed by user
  121. DataFromSoundIn(&buf, m_pOwner);
  122. // reuse the buffer:
  123. // prepare it again
  124. mmReturn = ::waveInPrepareHeader(m_hRecord,pHdr, sizeof(WAVEHDR));
  125. if(mmReturn)
  126. {
  127. waveInErrorMsg(mmReturn, "in OnWIM_DATA()");
  128. }
  129. else // no error
  130. {
  131. // add the input buffer to the queue again
  132. mmReturn = ::waveInAddBuffer(m_hRecord, pHdr, sizeof(WAVEHDR));
  133. if(mmReturn) waveInErrorMsg(mmReturn, "in OnWIM_DATA()");
  134. else return;  // no error
  135. }
  136. }
  137. // we are closing the waveIn handle, 
  138. // all data must be deleted
  139. // this buffer was allocated in Start()
  140. delete pHdr->lpData;
  141. delete pHdr;
  142. m_QueuedBuffers--;
  143. }
  144. int CSoundIn::AddInputBufferToQueue()
  145. {
  146. MMRESULT mmReturn = 0;
  147. // create the header
  148. LPWAVEHDR pHdr = new WAVEHDR;
  149. if(pHdr == NULL) return NULL;
  150. ZeroMemory(pHdr, sizeof(WAVEHDR));
  151. // new a buffer
  152. CBuffer buf(m_Format.nBlockAlign*m_BufferSize, false);
  153. pHdr->lpData = buf.ptr.c;
  154. pHdr->dwBufferLength = buf.ByteLen;
  155. // prepare it
  156. mmReturn = ::waveInPrepareHeader(m_hRecord,pHdr, sizeof(WAVEHDR));
  157. if(mmReturn)
  158. {
  159. waveInErrorMsg(mmReturn, "in AddInputBufferToQueue()");
  160. return m_QueuedBuffers;
  161. }
  162. // add the input buffer to the queue
  163. mmReturn = ::waveInAddBuffer(m_hRecord, pHdr, sizeof(WAVEHDR));
  164. if(mmReturn)
  165. {
  166. waveInErrorMsg(mmReturn, "in AddInputBufferToQueue()");
  167. return m_QueuedBuffers;
  168. }
  169. // no error
  170. // increment the number of waiting buffers
  171. return m_QueuedBuffers++;
  172. }
  173. void CSoundIn::waveInErrorMsg(MMRESULT result, LPCTSTR addstr)
  174. {
  175. // say error message
  176. char errorbuffer[100];
  177. waveInGetErrorText(result, errorbuffer,100);
  178. ErrorMsg("WAVEIN:%x:%s %s", result, errorbuffer, addstr);
  179. }