利用DirectSound实现声卡录音【老毕改版】【Part1】
这几天一直在研究DSOUND的录音及播放,为了能实现网络音视频打基础,呵呵,在网上查找了大量的相关资料,有一定的收货,其中大量的工作用来修改从网上找出的源码,因为太多错误的了,不太适合初学者,为此我特别封装成类,供初学者学习参考,欢迎批评指正!
/*类接口文件 ISound.h*/
- #pragma once
- #pragma comment(lib, "dxguid.lib")
- #pragma comment(lib, "dsound.lib")
- #include <mmsystem.h>
- #include <dsound.h>
- #include <string>
- #include "WaveFile.h"
- using namespace std;
- #define NOTIFICATIONS_PORTION 4
- class ISound
- {
- public:
- ISound()
- :m_dwBufferOffset(0),
- m_dwNotifySize(1000)
- {
- }
- virtual ~ISound();
- public:
- void SetFile(const char*);
- protected:
- virtual BOOL InitializeDevice() = 0;
- virtual BOOL UninitializeDevice() = 0;
- virtual BOOL CreateBuffer() = 0;
- virtual void WriteData() = 0;
- protected:
- string g_strfile;
- WAVEFORMATEX g_wformat;
- // 偏移量
- DWORD m_dwBufferOffset;
- // buffer size
- DWORD m_dwBufferSize;
- //
- DWORD m_dwNotifySize;
- // event handle
- HANDLE m_hEventNotify;
- };
- #include "StdAfx.h"
- #include "ISound.h"
- ISound::~ISound()
- {
- }
- void ISound::SetFile(const char* lpfile)
- {
- g_strfile = lpfile;
- }
- /*录音 CSoundRecord.h*/
- #pragma once
- #include "isound.h"
- class CSoundRecord :
- public ISound
- {
- public:
- CSoundRecord(void);
- ~CSoundRecord(void);
- private:
- LPDIRECTSOUNDCAPTURE8 m_lpCapture;
- LPDIRECTSOUNDCAPTUREBUFFER m_lpBuffer;
- LPDIRECTSOUNDCAPTUREBUFFER8 m_lpBuffer8;
- LPDIRECTSOUNDNOTIFY8 m_lpNotify;
- DSBPOSITIONNOTIFY m_NotifyPosition[NOTIFICATIONS_PORTION + 1];
- CWinThread* pThread;
- CWaveFile *m_pWaveFile;
- public:
- BOOL Record();
- BOOL Stop();
- protected:
- BOOL InitializeDevice();
- BOOL UninitializeDevice();
- protected:
- BOOL CreateBuffer();
- BOOL CreateNotification();
- void WriteData();
- void CorrectLocksize(LONG*);
- static UINT ThreadProc(LPVOID);
- };
- /*录音 CSoundRecord.cpp*/
- #include "StdAfx.h"
- #include "SoundRecord.h"
- //#include <boost/lexical_cast.hpp>
- //using namespace boost;
- CSoundRecord::CSoundRecord(void)
- {
- m_dwBufferSize = m_dwNotifySize*NOTIFICATIONS_PORTION;
- BOOL bResult = InitializeDevice();
- if(!bResult)
- {
- return;
- }
- bResult = CreateBuffer();
- if(!bResult)
- {
- return;
- }
- bResult = CreateNotification();
- if(!bResult)
- {
- return;
- }
- pThread = AfxBeginThread((AFX_THREADPROC)CSoundRecord::ThreadProc, this);
- m_pWaveFile = new CWaveFile;
- }
- CSoundRecord::~CSoundRecord(void)
- {
- UninitializeDevice();
- }
- BOOL CSoundRecord::Record()
- {
- if(g_strfile.empty())
- {
- return FALSE;
- }
- LPTSTR lpfile = (LPTSTR)g_strfile.c_str();
- HRESULT hr = m_pWaveFile->Open(lpfile, &g_wformat, WAVEFILE_WRITE);
- if(FAILED(hr))
- {
- m_pWaveFile->Close();
- return FALSE;
- }
- m_lpBuffer8->Start(DSCBSTART_LOOPING);
- return TRUE;
- }
- BOOL CSoundRecord::Stop()
- {
- m_lpBuffer8->Stop();
- m_pWaveFile->Close();
- return TRUE;
- }
- BOOL CSoundRecord::InitializeDevice()
- {
- HRESULT hr = DirectSoundCaptureCreate8(&DSDEVID_DefaultCapture, &m_lpCapture, NULL);
- if(FAILED(hr))
- {
- return FALSE;
- }
- return TRUE;
- }
- BOOL CSoundRecord::UninitializeDevice()
- {
- if(m_pWaveFile != NULL)
- {
- delete m_pWaveFile;
- }
- if(pThread)
- {
- pThread->Delete();
- }
- m_lpCapture->Release();
- return TRUE;
- }
- BOOL CSoundRecord::CreateBuffer()
- {
- ZeroMemory(&g_wformat, sizeof(g_wformat));
- g_wformat.wFormatTag = WAVE_FORMAT_PCM;
- g_wformat.nSamplesPerSec = 11025;//22050;
- g_wformat.wBitsPerSample = 8;
- g_wformat.nChannels = 1;
- g_wformat.nBlockAlign = g_wformat.nChannels * (g_wformat.wBitsPerSample / 8);
- g_wformat.nAvgBytesPerSec = g_wformat.nBlockAlign * g_wformat.nSamplesPerSec;
- g_wformat.cbSize = 0;
- DSCBUFFERDESC dscBufDesc;
- ZeroMemory(&dscBufDesc, sizeof(dscBufDesc));
- dscBufDesc.dwSize = sizeof(DSCBUFFERDESC);
- dscBufDesc.dwFlags = 0;// | DSBCAPS_CTRLVOLUME;
- dscBufDesc.dwBufferBytes = m_dwBufferSize;//m_wfx.nAvgBytesPerSec;
- dscBufDesc.dwReserved = 0;
- dscBufDesc.lpwfxFormat = &g_wformat;
- dscBufDesc.dwFXCount = 0;
- dscBufDesc.lpDSCFXDesc = NULL;
- HRESULT hr = m_lpCapture->CreateCaptureBuffer(&dscBufDesc, &m_lpBuffer, NULL);
- if(FAILED(hr))
- {
- return FALSE;
- }
- hr = m_lpBuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8, (LPVOID*)&m_lpBuffer8);
- if(FAILED(hr))
- {
- return FALSE;
- }
- m_lpBuffer->Release();
- return TRUE;
- }
- BOOL CSoundRecord::CreateNotification()
- {
- m_hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL);
- HRESULT hr = m_lpBuffer8->QueryInterface(IID_IDirectSoundNotify, (VOID**)&m_lpNotify);
- if(FAILED(hr))
- {
- return FALSE;
- }
- for (int i=0; i<NOTIFICATIONS_PORTION; i++)
- {
- m_NotifyPosition[i].dwOffset = (i + 1)*m_dwNotifySize - 1;
- m_NotifyPosition[i].hEventNotify = m_hEventNotify;
- }
- hr = m_lpNotify->SetNotificationPositions(NOTIFICATIONS_PORTION, m_NotifyPosition);
- if(FAILED(hr))
- {
- return FALSE;
- }
- return TRUE;
- }
- void CSoundRecord::WriteData()
- {
- DWORD dwReadPos;
- DWORD dwCapturePos;
- LONG lgLockSize;
- HRESULT hr = m_lpBuffer8->GetCurrentPosition(&dwCapturePos, &dwReadPos);
- if(FAILED(hr))
- {
- return;
- }
- lgLockSize = dwReadPos - m_dwBufferOffset;
- CorrectLocksize(&lgLockSize);
- VOID *pbCaptureData = NULL;
- DWORD dwCaptureLength = 0;
- VOID *pbCaptureData2 = NULL;
- DWORD dwCaptureLength2 = 0;
- UINT dwDataWrote;
- // lock
- hr = m_lpBuffer8->Lock(m_dwBufferOffset, lgLockSize,
- &pbCaptureData, &dwCaptureLength, &pbCaptureData2, &dwCaptureLength2,
- 0L);
- hr = m_pWaveFile->Write(dwCaptureLength, (BYTE*)pbCaptureData, &dwDataWrote);
- m_dwBufferOffset+=dwCaptureLength;
- m_dwBufferOffset%=m_dwBufferSize;
- if(pbCaptureData2 != NULL)
- {
- hr = m_pWaveFile->Write(dwCaptureLength2, (BYTE*)pbCaptureData2, &dwDataWrote);
- if(FAILED(hr))
- return;
- m_dwBufferOffset+=dwCaptureLength2;
- m_dwBufferOffset%=m_dwBufferSize;
- }
- // unlock
- m_lpBuffer8->Unlock(pbCaptureData, dwCaptureLength,
- pbCaptureData2, dwCaptureLength2);
- }
- UINT CSoundRecord::ThreadProc(LPVOID pParam)
- {
- CSoundRecord* pDSoundEx = (CSoundRecord*)pParam;
- DWORD dwResult;
- while (TRUE)
- {
- dwResult = MsgWaitForMultipleObjects(1, &pDSoundEx->m_hEventNotify, FALSE, INFINITE, NULL);
- switch(dwResult)
- {
- case WAIT_OBJECT_0 + 0:
- pDSoundEx->WriteData();
- }
- }
- return 0;
- }
- void CSoundRecord::CorrectLocksize(LONG* lpsize)
- {
- if(*lpsize < 0)
- {
- *lpsize += m_dwBufferSize;
- }
- //锁住内存的大小
- //这里取模是为了使得我们读取的数据大小为g_dwNotifySize整数倍,这样buffer里剩下的也是notify的倍数
- *lpsize -= (*lpsize%m_dwNotifySize);
- if (*lpsize <= 0)
- {
- return;
- }
- }
利用DirectSound实现声卡录音【老毕改版】【Part1】相关推荐
- java l老毕_她被毕福剑一手捧红,还给她牵线煤老板,老毕落难时她的做法超赞...
她被毕福剑一手捧红,还给她牵线煤老板,老毕落难时她的做法超赞 央视优秀的主持人有很多,但其中有一些人却已经淡出了大家的视线,比如说张蕾就是其中的代表.她主持的大多都是综艺类的节目,她独特的风格和清秀大 ...
- 黑马程序员_异常(老毕视频总结及《疯狂java》补充)
----------------------<ahref="http://edu.csdn.net"target="blank">ASP.Net+A ...
- 黑马程序员__关于自己的一些学习死角的再学习(基于老毕的java基础视频)
----------------------<ahref="http://edu.csdn.net"target="blank">ASP.Net+A ...
- 传智博客第一天——传智播客的老毕
其实我选择传智播客的原因很简单,网上有张孝祥老师的视频,敢于分享自己课堂视频的势必是对自己讲课的自信,再就是离家近. 一个培训机构的核心竞争力是什么,是高广大楼?是冠冕广告?还是拍胸脯说只要你毕业就能 ...
- STM32 USB声卡录音(USB Microphone),基于CubeMX修改
目录 说明 CubeMX配置 Pinout Clock Configuration Configuration 工程设置 代码工程修改 修改USB设备描述符 修改数据传输配置 声卡测试 说明 Cube ...
- 利用Directsound编程实现实时混音
在游戏开发中比较常用的音效素材都是比较短的,所以一般常用的API是playsound()函数,比如我们要在游戏背景中播放一个test.wav音效素材,只要简单的调用下面的函数即可 PlaySound( ...
- 黑客利用瑞昱声卡设计缺陷监听你?
在防止黑客窃取隐私信息方面人们通常都会更多关注软件防护,比如安装防火墙.防病毒软件,了不起的弄一个硬盘物理加密.不过,黑客们目前已经另辟蹊径,找到了我们计算机上硬件上最隐蔽的环节来实施攻击--声卡.而 ...
- 老网站改版,百度网站SEO改版工具,没这样做准后悔
做网站经常会面临一个问题网站改版,站在SEO的角度看经常性的改版对收录和排名非常不利,但是有时候不改版确实是不行的,因为思路总是在不断的变化,网站页面用户体验也是在改版过程中不断的完善. 使用网站改版 ...
- Android NDK(二)最最简单的方法利用NDK实现MP3录音
首先了解到调用android原生的录音无法生成MP3格式,其次java无法实现对文件的转码(个人见解),所以采用libmp3lame把AudioRecord音频流直接转换成MP3格式.这里采用的是最新 ...
最新文章
- Python多线程调试
- ipconfig不是内部或外部_OSPF外部路由详解-LSA4-LSA5
- mysql的数据现实在小程序_使用phpstudy将本地mysql数据显示在微信小程序前端
- Python中面向对象的讲解(2)
- 数据结构与算法 | 栈
- 10月31日,面试题小结
- Codeforces Round #668 (Div. 2)
- 使用arthas排查cpu飙高问题
- 用控制台怎么编译java程序_怎么在cmd中运行java控制台程序?
- 她,18岁,李飞飞三度公开表扬,高中时NIPS获奖,创造「AI手术教练」
- MyEclipse10 离线图文安装SVN插件教程
- Luogu P4109 [HEOI2015]定价 贪心
- java 字符串转long_如何在Java中将String转换为long?
- pr用什么显卡比较好_用PR软件做后期剪辑,主要需要怎样的主机配置-百度经验...
- 实现在线预览word文档
- entrez检索系统要服务器吗,Entrez 系统
- 2022基金定投数字货币理财程序源码
- C语言算法题:一只小蜜蜂...
- matlab三相触发电路图,三相过零触发电路图
- 视频编码基础:I帧、P帧 和 B 帧
热门文章
- 【转】“蚁族” 的生活方式画像
- P57 3-3数数字
- python 新媒体 岗位_python新媒体运营 编程python可以干什么
- java swing substance_java swing皮肤使用(substance)
- 基于javaweb+SSM的大学生兼职论坛(java+SSM+JSP+jQuery+Layui+mysql)
- LeetCode 452 射气球问题
- The Definitive Guide to Catalyst
- c++中文正则的使用
- 【阿里云峰会】云上护航服务—保障云上的尖峰时刻...
- Dokcer安装青龙面板-京东豆天天领到手软