这几天一直在研究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. virtual ~ISound();
  19. public:
  20. void SetFile(const char*);
  21. protected:
  22. virtual BOOL InitializeDevice() = 0;
  23. virtual BOOL UninitializeDevice() = 0;
  24. virtual BOOL CreateBuffer() = 0;
  25. virtual void WriteData() = 0;
  26. protected:
  27. string g_strfile;
  28. WAVEFORMATEX g_wformat;
  29. // 偏移量
  30. DWORD m_dwBufferOffset;
  31. // buffer size
  32. DWORD m_dwBufferSize;
  33. //
  34. DWORD m_dwNotifySize;
  35. // event handle
  36. HANDLE m_hEventNotify;
  37. };
/*类接口文件 ISound.h*/

  1. #include "StdAfx.h"
  2. #include "ISound.h"
  3. ISound::~ISound()
  4. {
  5. }
  6. void ISound::SetFile(const char* lpfile)
  7. {
  8. g_strfile = lpfile;
  9. }
  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. DSBPOSITIONNOTIFY m_NotifyPosition[NOTIFICATIONS_PORTION + 1];
  16. CWinThread* pThread;
  17. CWaveFile *m_pWaveFile;
  18. public:
  19. BOOL Record();
  20. BOOL Stop();
  21. protected:
  22. BOOL InitializeDevice();
  23. BOOL UninitializeDevice();
  24. protected:
  25. BOOL CreateBuffer();
  26. BOOL CreateNotification();
  27. void WriteData();
  28. void CorrectLocksize(LONG*);
  29. static UINT ThreadProc(LPVOID);
  30. };
  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. HRESULT hr = m_lpCapture->CreateCaptureBuffer(&dscBufDesc, &m_lpBuffer, NULL);
  95. if(FAILED(hr))
  96. {
  97. return FALSE;
  98. }
  99. hr = m_lpBuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)&m_lpBuffer8);
  100. if(FAILED(hr))
  101. {
  102. return FALSE;
  103. }
  104. m_lpBuffer->Release();
  105. return TRUE;
  106. }
  107. BOOL CSoundRecord::CreateNotification()
  108. {
  109. m_hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL);
  110. HRESULT hr = m_lpBuffer8->QueryInterface(IID_IDirectSoundNotify, (VOID**)&m_lpNotify);
  111. if(FAILED(hr))
  112. {
  113. return FALSE;
  114. }
  115. for (int i=0; i<NOTIFICATIONS_PORTION; i++)
  116. {
  117. m_NotifyPosition[i].dwOffset = (i + 1)*m_dwNotifySize - 1;
  118. m_NotifyPosition[i].hEventNotify = m_hEventNotify;
  119. }
  120. hr = m_lpNotify->SetNotificationPositions(NOTIFICATIONS_PORTION, m_NotifyPosition);
  121. if(FAILED(hr))
  122. {
  123. return FALSE;
  124. }
  125. return TRUE;
  126. }
  127. void CSoundRecord::WriteData()
  128. {
  129. DWORD dwReadPos;
  130. DWORD dwCapturePos;
  131. LONG lgLockSize;
  132. HRESULT hr = m_lpBuffer8->GetCurrentPosition(&dwCapturePos, &dwReadPos);
  133. if(FAILED(hr))
  134. {
  135. return;
  136. }
  137. lgLockSize = dwReadPos - m_dwBufferOffset;
  138. CorrectLocksize(&lgLockSize);
  139. VOID *pbCaptureData = NULL;
  140. DWORD dwCaptureLength = 0;
  141. VOID *pbCaptureData2 = NULL;
  142. DWORD dwCaptureLength2 = 0;
  143. UINT dwDataWrote;
  144. // lock
  145. hr = m_lpBuffer8->Lock(m_dwBufferOffset, lgLockSize,
  146. &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2,
  147. 0L);
  148. hr = m_pWaveFile->Write(dwCaptureLength, (BYTE*)pbCaptureData, &dwDataWrote);
  149. m_dwBufferOffset+=dwCaptureLength;
  150. m_dwBufferOffset%=m_dwBufferSize;
  151. if(pbCaptureData2 != NULL)
  152. {
  153. hr = m_pWaveFile->Write(dwCaptureLength2, (BYTE*)pbCaptureData2, &dwDataWrote);
  154. if(FAILED(hr))
  155. return;
  156. m_dwBufferOffset+=dwCaptureLength2;
  157. m_dwBufferOffset%=m_dwBufferSize;
  158. }
  159. // unlock
  160. m_lpBuffer8->Unlock(pbCaptureData, dwCaptureLength,
  161. pbCaptureData2, dwCaptureLength2);
  162. }
  163. UINT CSoundRecord::ThreadProc(LPVOID pParam)
  164. {
  165. CSoundRecord* pDSoundEx = (CSoundRecord*)pParam;
  166. DWORD dwResult;
  167. while (TRUE)
  168. {
  169. dwResult = MsgWaitForMultipleObjects(1, &pDSoundEx->m_hEventNotify, FALSE, INFINITE, NULL);
  170. switch(dwResult)
  171. {
  172. case WAIT_OBJECT_0 + 0:
  173. pDSoundEx->WriteData();
  174. }
  175. }
  176. return 0;
  177. }
  178. void CSoundRecord::CorrectLocksize(LONG* lpsize)
  179. {
  180. if(*lpsize < 0)
  181. {
  182. *lpsize += m_dwBufferSize;
  183. }
  184. //锁住内存的大小
  185. //这里取模是为了使得我们读取的数据大小为g_dwNotifySize整数倍,这样buffer里剩下的也是notify的倍数
  186. *lpsize -= (*lpsize%m_dwNotifySize);
  187. if (*lpsize <= 0)
  188. {
  189. return;
  190. }
  191. }

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

  1. java l老毕_她被毕福剑一手捧红,还给她牵线煤老板,老毕落难时她的做法超赞...

    她被毕福剑一手捧红,还给她牵线煤老板,老毕落难时她的做法超赞 央视优秀的主持人有很多,但其中有一些人却已经淡出了大家的视线,比如说张蕾就是其中的代表.她主持的大多都是综艺类的节目,她独特的风格和清秀大 ...

  2. 黑马程序员_异常(老毕视频总结及《疯狂java》补充)

    ----------------------<ahref="http://edu.csdn.net"target="blank">ASP.Net+A ...

  3. 黑马程序员__关于自己的一些学习死角的再学习(基于老毕的java基础视频)

    ----------------------<ahref="http://edu.csdn.net"target="blank">ASP.Net+A ...

  4. 传智博客第一天——传智播客的老毕

    其实我选择传智播客的原因很简单,网上有张孝祥老师的视频,敢于分享自己课堂视频的势必是对自己讲课的自信,再就是离家近. 一个培训机构的核心竞争力是什么,是高广大楼?是冠冕广告?还是拍胸脯说只要你毕业就能 ...

  5. STM32 USB声卡录音(USB Microphone),基于CubeMX修改

    目录 说明 CubeMX配置 Pinout Clock Configuration Configuration 工程设置 代码工程修改 修改USB设备描述符 修改数据传输配置 声卡测试 说明 Cube ...

  6. 利用Directsound编程实现实时混音

    在游戏开发中比较常用的音效素材都是比较短的,所以一般常用的API是playsound()函数,比如我们要在游戏背景中播放一个test.wav音效素材,只要简单的调用下面的函数即可 PlaySound( ...

  7. 黑客利用瑞昱声卡设计缺陷监听你?

    在防止黑客窃取隐私信息方面人们通常都会更多关注软件防护,比如安装防火墙.防病毒软件,了不起的弄一个硬盘物理加密.不过,黑客们目前已经另辟蹊径,找到了我们计算机上硬件上最隐蔽的环节来实施攻击--声卡.而 ...

  8. 老网站改版,百度网站SEO改版工具,没这样做准后悔

    做网站经常会面临一个问题网站改版,站在SEO的角度看经常性的改版对收录和排名非常不利,但是有时候不改版确实是不行的,因为思路总是在不断的变化,网站页面用户体验也是在改版过程中不断的完善. 使用网站改版 ...

  9. Android NDK(二)最最简单的方法利用NDK实现MP3录音

    首先了解到调用android原生的录音无法生成MP3格式,其次java无法实现对文件的转码(个人见解),所以采用libmp3lame把AudioRecord音频流直接转换成MP3格式.这里采用的是最新 ...

最新文章

  1. Python多线程调试
  2. ipconfig不是内部或外部_OSPF外部路由详解-LSA4-LSA5
  3. mysql的数据现实在小程序_使用phpstudy将本地mysql数据显示在微信小程序前端
  4. Python中面向对象的讲解(2)
  5. 数据结构与算法 | 栈
  6. 10月31日,面试题小结
  7. Codeforces Round #668 (Div. 2)
  8. 使用arthas排查cpu飙高问题
  9. 用控制台怎么编译java程序_怎么在cmd中运行java控制台程序?
  10. 她,18岁,李飞飞三度公开表扬,高中时NIPS获奖,创造「AI手术教练」
  11. MyEclipse10 离线图文安装SVN插件教程
  12. Luogu P4109 [HEOI2015]定价 贪心
  13. java 字符串转long_如何在Java中将String转换为long?
  14. pr用什么显卡比较好_用PR软件做后期剪辑,主要需要怎样的主机配置-百度经验...
  15. 实现在线预览word文档
  16. entrez检索系统要服务器吗,Entrez 系统
  17. 2022基金定投数字货币理财程序源码
  18. C语言算法题:一只小蜜蜂...
  19. matlab三相触发电路图,三相过零触发电路图
  20. 视频编码基础:I帧、P帧 和 B 帧

热门文章

  1. 【转】“蚁族” 的生活方式画像
  2. P57 3-3数数字
  3. python 新媒体 岗位_python新媒体运营 编程python可以干什么
  4. java swing substance_java swing皮肤使用(substance)
  5. 基于javaweb+SSM的大学生兼职论坛(java+SSM+JSP+jQuery+Layui+mysql)
  6. LeetCode 452 射气球问题
  7. The Definitive Guide to Catalyst
  8. c++中文正则的使用
  9. 【阿里云峰会】云上护航服务—保障云上的尖峰时刻...
  10. Dokcer安装青龙面板-京东豆天天领到手软