利用DirectSound实现声卡录音【老毕改版】【Part2】

来源:互联网 发布:百度网络问诊 编辑:程序博客网 时间:2024/05/22 16:52
请接着利用DirectSound实现声卡录音【老毕改版】【Part1】 继续!

 

  1. /*CSoundPlay.h*/
  2. #pragma once
  3. #include "isound.h"
  4. class CSoundPlay :
  5.     public ISound
  6. {
  7. public:
  8.     CSoundPlay(void);
  9.     ~CSoundPlay(void);
  10. public:
  11.     BOOL Play(void);
  12.     BOOL Pause(void);
  13.     BOOL Stop(void);
  14.     void SetCurWnd(HWND hWnd);
  15. protected:
  16.     BOOL InitializeDevice(void);
  17.     BOOL UninitializeDevice(void);
  18.     BOOL CreateBuffer(void);
  19.     void WriteData();
  20.     BOOL CreateNotification();
  21. private:
  22.     static UINT ThreadProc(LPVOID); 
  23. private:
  24.     HWND m_hWnd;
  25.     // Main Buffer
  26.     LPDIRECTSOUNDBUFFER m_lpBuffer;
  27.     // Secondary Buffer
  28.     LPDIRECTSOUNDBUFFER8 m_lpBuffer8;
  29.     LPDIRECTSOUNDNOTIFY8 m_lpNotify;
  30.     // Device
  31.     LPDIRECTSOUND8 m_lpDevice;
  32.     CWaveFile *m_pWaveFile;
  33.     CWinThread* pThread;
  34.     DSBPOSITIONNOTIFY m_NotifyPosition[NOTIFICATIONS_PORTION + 1];  
  35.     BOOL m_bFinished;
  36. public:
  37.     float GetTimeLen(void);
  38.     BOOL PlayBySystem(void);
  39. };

 

 

  1. /*CSoundPlay.cpp*/
  2. #include "StdAfx.h"
  3. #include "SoundPlay.h"
  4. CSoundPlay::CSoundPlay(void):
  5. m_bFinished(FALSE)
  6. {
  7.     m_dwBufferSize = m_dwNotifySize*NOTIFICATIONS_PORTION;
  8.     m_pWaveFile = new CWaveFile;
  9. }
  10. CSoundPlay::~CSoundPlay(void)
  11. {
  12.     UninitializeDevice();
  13. }
  14. BOOL CSoundPlay::Play(void)
  15. {
  16.     HRESULT hr = m_pWaveFile->Open((LPTSTR)g_strfile.c_str(), &g_wformat, WAVEFILE_READ);
  17.     if(FAILED(hr))
  18.     {
  19.         return FALSE;
  20.     }
  21.     try
  22.     {
  23.         CreateBuffer();
  24.         CreateNotification();
  25.         m_lpBuffer8->SetVolume(400);
  26.         m_bFinished = FALSE;
  27.         pThread = AfxBeginThread((AFX_THREADPROC)ThreadProc, this);
  28.         return TRUE;
  29.     }   
  30.     catch (CException* e)
  31.     {
  32.         throw e;
  33.     }
  34.     return FALSE;
  35. }
  36. BOOL CSoundPlay::Pause(void)
  37. {   
  38.     return 0;
  39. }
  40. BOOL CSoundPlay::Stop(void)
  41. {
  42.     m_lpBuffer->Stop();
  43.     if(pThread)
  44.         pThread->Delete();
  45.     m_pWaveFile->Close();
  46.     return 0;
  47. }
  48. BOOL CSoundPlay::CreateBuffer(void)
  49. {   
  50.     DWORD dwSizeRead = m_dwBufferSize;
  51.     DSBUFFERDESC dsBufDesc;
  52.     ZeroMemory(&dsBufDesc, sizeof(DSBUFFERDESC));
  53.     dsBufDesc.dwSize = sizeof(DSBUFFERDESC);
  54.     dsBufDesc.dwFlags =DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPOSITIONNOTIFY|
  55.         DSBCAPS_CTRLFREQUENCY|DSBCAPS_GLOBALFOCUS;
  56.     dsBufDesc.dwBufferBytes = dwSizeRead;
  57.     dsBufDesc.lpwfxFormat = m_pWaveFile->GetFormat();
  58.     HRESULT hr = m_lpDevice->CreateSoundBuffer(&dsBufDesc, &m_lpBuffer, NULL);
  59.     if(FAILED(hr))
  60.     {
  61.         return FALSE;
  62.     }
  63.     hr = m_lpBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&m_lpBuffer8);
  64.     if(FAILED(hr))
  65.     {
  66.         return FALSE;
  67.     }
  68.     m_lpBuffer->Release();
  69.     return TRUE;
  70. }
  71. BOOL CSoundPlay::InitializeDevice(void)
  72. {
  73.     HRESULT hr = DirectSoundCreate8(NULL, &m_lpDevice, NULL);
  74.     if(FAILED(hr))
  75.     {
  76.         return FALSE;
  77.     }   
  78.     hr = m_lpDevice->SetCooperativeLevel(m_hWnd, DSSCL_PRIORITY);
  79.     if(FAILED(hr))
  80.     {
  81.         return FALSE;
  82.     }
  83.     return TRUE;
  84. }
  85. BOOL CSoundPlay::UninitializeDevice(void)
  86. {
  87.     if(m_pWaveFile != NULL)
  88.     {
  89.         delete m_pWaveFile;
  90.     }
  91.     if(m_lpDevice != NULL)
  92.         m_lpDevice->Release();
  93.     return TRUE;
  94. }
  95. UINT CSoundPlay::ThreadProc(LPVOID lpParam)
  96. {
  97.     CSoundPlay* lpSoundPlay = (CSoundPlay*)lpParam;
  98.     LPVOID lpLockbuf;
  99.     DWORD dwLen;
  100.     DWORD dwWrite;
  101.     lpSoundPlay->m_lpBuffer8->Lock(0, 0, &lpLockbuf, &dwLen, NULL, NULL, DSBLOCK_ENTIREBUFFER);
  102.     lpSoundPlay->m_pWaveFile->Read((BYTE*)lpLockbuf, dwLen, &dwWrite);
  103.     lpSoundPlay->m_lpBuffer8->Unlock(lpLockbuf, dwLen, NULL, 0);
  104.     lpSoundPlay->m_lpBuffer8->SetCurrentPosition(0);
  105.     lpSoundPlay->m_lpBuffer8->Play(0, 0, DSBPLAY_LOOPING);
  106.     DWORD dwResult;
  107.     while (!lpSoundPlay->m_bFinished)
  108.     {
  109.         dwResult = MsgWaitForMultipleObjects(1, &lpSoundPlay->m_hEventNotify, FALSE, INFINITE, NULL);
  110.         switch(dwResult)
  111.         {
  112.             case WAIT_OBJECT_0:
  113.                 lpSoundPlay->WriteData();
  114.         }
  115.     }
  116.     lpSoundPlay->m_lpBuffer8->Stop();
  117.     return 0;
  118. }
  119. BOOL CSoundPlay::CreateNotification()
  120. {
  121.     m_hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL);
  122.     HRESULT hr = m_lpBuffer8->QueryInterface(IID_IDirectSoundNotify, (VOID**)&m_lpNotify);
  123.     if(FAILED(hr))
  124.     {
  125.         return FALSE;
  126.     }
  127.     for (int i=0; i<NOTIFICATIONS_PORTION; i++)
  128.     {
  129.         m_NotifyPosition[i].dwOffset = (i + 1)*m_dwNotifySize - 1;
  130.         m_NotifyPosition[i].hEventNotify = m_hEventNotify;
  131.     }
  132.     hr = m_lpNotify->SetNotificationPositions(NOTIFICATIONS_PORTION, m_NotifyPosition);
  133.     if(FAILED(hr))
  134.     {
  135.         return FALSE;
  136.     }
  137.     return TRUE;
  138. }
  139. void CSoundPlay::WriteData()
  140. {
  141.     VOID *pbCaptureData = NULL;
  142.     DWORD dwCaptureLength = 0;
  143.     VOID *pbCaptureData2 = NULL;
  144.     DWORD dwCaptureLength2 = 0;
  145.     UINT dwDataWrote;   
  146.     DWORD dwBytesWrittenToBuf;
  147.     HRESULT hr = m_lpBuffer8->Lock(m_dwBufferOffset, m_dwNotifySize, 
  148.         &pbCaptureData, &dwCaptureLength,
  149.         &pbCaptureData2, &dwCaptureLength2, 
  150.         0L);
  151.     if(hr == DSERR_BUFFERLOST)
  152.     {
  153.         m_lpBuffer8->Restore();
  154.         hr = m_lpBuffer8->Lock(m_dwBufferOffset, m_dwNotifySize, 
  155.             &pbCaptureData, &dwCaptureLength,
  156.             &pbCaptureData2, &dwCaptureLength2, 
  157.             0L);
  158.     }
  159.     if(SUCCEEDED(hr))
  160.     {
  161.         hr = m_pWaveFile->Read((BYTE*)pbCaptureData, dwCaptureLength, &dwBytesWrittenToBuf);
  162.         if(pbCaptureData2 != NULL)
  163.         {
  164.             hr = m_pWaveFile->Read((BYTE*)pbCaptureData2, dwCaptureLength2, &dwBytesWrittenToBuf);
  165.         }
  166.         m_dwBufferOffset += dwBytesWrittenToBuf;
  167.         m_dwBufferOffset %= m_dwBufferSize;
  168.         if(dwBytesWrittenToBuf < m_dwNotifySize)
  169.         {
  170.             FillMemory((BYTE*)pbCaptureData + dwBytesWrittenToBuf, 
  171.                 m_dwNotifySize-dwBytesWrittenToBuf, 
  172.                 (BYTE)(m_pWaveFile->m_pwfx->wBitsPerSample == 8 ? 128 : 0 ) );
  173.             m_bFinished = TRUE;
  174.         }
  175.         m_lpBuffer8->Unlock(pbCaptureData, dwCaptureLength, 
  176.             pbCaptureData2, dwCaptureLength2);  
  177.     }
  178. }
  179. void CSoundPlay::SetCurWnd(HWND hWnd)
  180. {
  181.     m_hWnd = hWnd;
  182.     InitializeDevice();
  183. }
  184. float CSoundPlay::GetTimeLen(void)
  185. {
  186.     DWORD dwSize = m_pWaveFile->GetSize();
  187.     return dwSize/g_wformat.nSamplesPerSec;
  188. }
  189. BOOL CSoundPlay::PlayBySystem(void)
  190. {
  191.     HRESULT hr = PlaySound((LPCTSTR)g_strfile.c_str(), NULL, SND_ASYNC|SND_NODEFAULT);
  192.     if (hr == S_OK)
  193.     {
  194.         return TRUE;
  195.     }
  196.     return FALSE;
  197. }
原创粉丝点击