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

40 篇文章 0 订阅
26 篇文章 0 订阅

这几天一直在研究DSOUND的录音及播放,为了能实现网络音视频打基础,呵呵,在网上查找了大量的相关资料,有一定的收货,其中大量的工作用来修改从网上找出的源码,因为太多错误的了,不太适合初学者,为此我特别封装成类,供初学者学习参考,欢迎批评指正!

/*类接口文件 ISound.h*/

  1. #pragma once
  2. #pragma comment(lib, "dxguid.lib")
  3. #pragma comment(lib, "dsound.lib")
  4. #include <mmsystem.h>
  5. #include <dsound.h>
  6. #include <string>
  7. #include "WaveFile.h"
  8. using namespace std;
  9. #define NOTIFICATIONS_PORTION 4
  10. class ISound
  11. {
  12. public
  13.     ISound()
  14.         :m_dwBufferOffset(0),
  15.         m_dwNotifySize(1000)
  16.         
  17.     {
  18.         
  19.     }
  20.     virtual ~ISound();
  21. public:
  22.     void SetFile(const char*);
  23. protected:
  24.     virtual BOOL InitializeDevice() = 0;
  25.     virtual BOOL UninitializeDevice() = 0;
  26.     virtual BOOL CreateBuffer() = 0;
  27.     virtual void WriteData() = 0;
  28. protected:
  29.     string g_strfile;
  30.     WAVEFORMATEX g_wformat;
  31.     // 偏移量
  32.     DWORD m_dwBufferOffset;
  33.     // buffer size
  34.     DWORD m_dwBufferSize;
  35.     //
  36.     DWORD m_dwNotifySize;
  37.     // event handle
  38.     HANDLE m_hEventNotify;
  39. };
/*类接口文件 ISound.h*/
  1. #include "StdAfx.h"
  2. #include "ISound.h"
  3. ISound::~ISound()
  4. {
  5.     
  6. }
  7. void ISound::SetFile(const char* lpfile)
  8. {   
  9.     g_strfile = lpfile;
  10. }
 
  1. /*录音 CSoundRecord.h*/
  2. #pragma once
  3. #include "isound.h"
  4. class CSoundRecord :
  5.     public ISound
  6. {
  7. public:
  8.     CSoundRecord(void);
  9.     ~CSoundRecord(void);
  10. private:
  11.     LPDIRECTSOUNDCAPTURE8 m_lpCapture;
  12.     LPDIRECTSOUNDCAPTUREBUFFER m_lpBuffer;
  13.     LPDIRECTSOUNDCAPTUREBUFFER8 m_lpBuffer8;
  14.     LPDIRECTSOUNDNOTIFY8 m_lpNotify;
  15.     
  16.     DSBPOSITIONNOTIFY m_NotifyPosition[NOTIFICATIONS_PORTION + 1];  
  17.     CWinThread* pThread;
  18.     CWaveFile *m_pWaveFile;
  19. public:
  20.     BOOL Record();
  21.     BOOL Stop();
  22. protected:
  23.     BOOL InitializeDevice();
  24.     BOOL UninitializeDevice();
  25. protected:
  26.     BOOL CreateBuffer();
  27.     BOOL CreateNotification();
  28.     void WriteData();
  29.     void CorrectLocksize(LONG*);
  30.     static UINT ThreadProc(LPVOID);
  31. };

 

  1. /*录音 CSoundRecord.cpp*/
  2. #include "StdAfx.h"
  3. #include "SoundRecord.h"
  4. //#include <boost/lexical_cast.hpp>
  5. //using namespace boost;
  6. CSoundRecord::CSoundRecord(void)
  7. {
  8.     m_dwBufferSize = m_dwNotifySize*NOTIFICATIONS_PORTION;
  9.     BOOL bResult = InitializeDevice();
  10.     if(!bResult)
  11.     {
  12.         return;
  13.     }
  14.     bResult = CreateBuffer();
  15.     if(!bResult)
  16.     {
  17.         return;
  18.     }
  19.     bResult = CreateNotification();
  20.     if(!bResult)
  21.     {
  22.         return;
  23.     }
  24.     pThread = AfxBeginThread((AFX_THREADPROC)CSoundRecord::ThreadProc, this);
  25.     m_pWaveFile = new CWaveFile;
  26. }
  27. CSoundRecord::~CSoundRecord(void)
  28. {
  29.     UninitializeDevice();
  30. }
  31. BOOL CSoundRecord::Record()
  32. {
  33.     if(g_strfile.empty())
  34.     {
  35.         return FALSE;
  36.     }
  37.     LPTSTR lpfile = (LPTSTR)g_strfile.c_str();
  38.     HRESULT hr = m_pWaveFile->Open(lpfile, &g_wformat, WAVEFILE_WRITE);
  39.     if(FAILED(hr))
  40.     {
  41.         m_pWaveFile->Close();
  42.         return FALSE;
  43.     }
  44.     m_lpBuffer8->Start(DSCBSTART_LOOPING);
  45.     return TRUE;
  46. }
  47. BOOL CSoundRecord::Stop()
  48. {
  49.     m_lpBuffer8->Stop();
  50.     m_pWaveFile->Close();
  51.     return TRUE;
  52. }
  53. BOOL CSoundRecord::InitializeDevice()
  54. {
  55.     HRESULT hr = DirectSoundCaptureCreate8(&DSDEVID_DefaultCapture, &m_lpCapture, NULL);
  56.     if(FAILED(hr))
  57.     {
  58.         return FALSE;
  59.     }
  60.     return TRUE;
  61. }
  62. BOOL CSoundRecord::UninitializeDevice()
  63. {
  64.     if(m_pWaveFile != NULL) 
  65.     {
  66.         delete m_pWaveFile;
  67.     }
  68.     if(pThread)
  69.     {
  70.         pThread->Delete();
  71.     }
  72.     m_lpCapture->Release();
  73.     return TRUE;
  74. }
  75. BOOL CSoundRecord::CreateBuffer()
  76. {
  77.     ZeroMemory(&g_wformat, sizeof(g_wformat));
  78.     g_wformat.wFormatTag = WAVE_FORMAT_PCM;
  79.     g_wformat.nSamplesPerSec = 11025;//22050;
  80.     g_wformat.wBitsPerSample = 8;
  81.     g_wformat.nChannels = 1;
  82.     g_wformat.nBlockAlign = g_wformat.nChannels * (g_wformat.wBitsPerSample / 8);
  83.     g_wformat.nAvgBytesPerSec = g_wformat.nBlockAlign * g_wformat.nSamplesPerSec;
  84.     g_wformat.cbSize = 0;
  85.     DSCBUFFERDESC dscBufDesc;
  86.     ZeroMemory(&dscBufDesc, sizeof(dscBufDesc));
  87.     dscBufDesc.dwSize = sizeof(DSCBUFFERDESC);
  88.     dscBufDesc.dwFlags = 0;// | DSBCAPS_CTRLVOLUME;
  89.     dscBufDesc.dwBufferBytes = m_dwBufferSize;//m_wfx.nAvgBytesPerSec;
  90.     dscBufDesc.dwReserved = 0;
  91.     dscBufDesc.lpwfxFormat = &g_wformat;
  92.     dscBufDesc.dwFXCount = 0;
  93.     dscBufDesc.lpDSCFXDesc = NULL;  
  94.     
  95.     HRESULT hr = m_lpCapture->CreateCaptureBuffer(&dscBufDesc, &m_lpBuffer, NULL);
  96.     if(FAILED(hr))
  97.     {
  98.         return FALSE;
  99.     }
  100.     hr = m_lpBuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)&m_lpBuffer8);
  101.     if(FAILED(hr))
  102.     {
  103.         return FALSE;
  104.     }
  105.     m_lpBuffer->Release();
  106.     
  107.     return TRUE;
  108. }
  109. BOOL CSoundRecord::CreateNotification()
  110. {
  111.     m_hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL);
  112.     HRESULT hr = m_lpBuffer8->QueryInterface(IID_IDirectSoundNotify, (VOID**)&m_lpNotify);
  113.     if(FAILED(hr))
  114.     {
  115.         return FALSE;
  116.     }
  117.     for (int i=0; i<NOTIFICATIONS_PORTION; i++)
  118.     {
  119.         m_NotifyPosition[i].dwOffset = (i + 1)*m_dwNotifySize - 1;
  120.         m_NotifyPosition[i].hEventNotify = m_hEventNotify;
  121.     }
  122.     hr = m_lpNotify->SetNotificationPositions(NOTIFICATIONS_PORTION, m_NotifyPosition);
  123.     if(FAILED(hr))
  124.     {
  125.         return FALSE;
  126.     }
  127.     return TRUE;
  128. }
  129. void CSoundRecord::WriteData()
  130. {
  131.     DWORD dwReadPos;
  132.     DWORD dwCapturePos;
  133.     LONG lgLockSize;
  134.     HRESULT hr = m_lpBuffer8->GetCurrentPosition(&dwCapturePos, &dwReadPos);
  135.     if(FAILED(hr))
  136.     {
  137.         return;
  138.     }
  139.     lgLockSize = dwReadPos - m_dwBufferOffset;
  140.     CorrectLocksize(&lgLockSize);
  141.     VOID *pbCaptureData = NULL;
  142.     DWORD dwCaptureLength = 0;
  143.     VOID *pbCaptureData2 = NULL;
  144.     DWORD dwCaptureLength2 = 0;
  145.     UINT dwDataWrote;   
  146.     // lock 
  147.     hr = m_lpBuffer8->Lock(m_dwBufferOffset, lgLockSize, 
  148.         &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2, 
  149.         0L);
  150.     hr = m_pWaveFile->Write(dwCaptureLength, (BYTE*)pbCaptureData, &dwDataWrote);
  151.     m_dwBufferOffset+=dwCaptureLength;
  152.     m_dwBufferOffset%=m_dwBufferSize;
  153.     if(pbCaptureData2 != NULL)
  154.     {
  155.         hr = m_pWaveFile->Write(dwCaptureLength2, (BYTE*)pbCaptureData2, &dwDataWrote);
  156.         if(FAILED(hr))
  157.             return;
  158.         m_dwBufferOffset+=dwCaptureLength2;
  159.         m_dwBufferOffset%=m_dwBufferSize;
  160.     }
  161.     // unlock
  162.     m_lpBuffer8->Unlock(pbCaptureData, dwCaptureLength, 
  163.         pbCaptureData2, dwCaptureLength2);  
  164. }
  165. UINT CSoundRecord::ThreadProc(LPVOID pParam)
  166. {
  167.     CSoundRecord* pDSoundEx = (CSoundRecord*)pParam;
  168.     DWORD dwResult;
  169.     while (TRUE)
  170.     {
  171.         dwResult = MsgWaitForMultipleObjects(1, &pDSoundEx->m_hEventNotify, FALSE, INFINITE, NULL);
  172.         switch(dwResult)
  173.         {
  174.         case WAIT_OBJECT_0 + 0:
  175.             pDSoundEx->WriteData();
  176.         }
  177.     }
  178.     return 0;
  179. }
  180. void CSoundRecord::CorrectLocksize(LONG* lpsize)
  181. {
  182.     if(*lpsize < 0)
  183.     {
  184.         *lpsize += m_dwBufferSize;
  185.     }
  186.     //锁住内存的大小
  187.     //这里取模是为了使得我们读取的数据大小为g_dwNotifySize整数倍,这样buffer里剩下的也是notify的倍数
  188.     *lpsize -= (*lpsize%m_dwNotifySize);
  189.     if (*lpsize <= 0)
  190.     {
  191.         return;
  192.     }
  193. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值