利用DirectSound实现声卡录音【老毕改版】【Part1】
来源:互联网 发布:二分搜索递归算法 编辑:程序博客网 时间:2024/05/16 01:58
这几天一直在研究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;
- };
/*类接口文件 ISound.h*/
- #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】
- 利用DirectSound实现声卡录音【老毕改版】【Part2】
- 利用DirectSound实现声卡录音【老毕改版】【Part3】
- 利用DirectSound实现声卡录音【老毕改版】【Part4】
- 利用DirectSound实现声卡录音
- 利用DirectSound实现声卡录音
- 利用DirectSound实现声卡录音
- 利用DirectSound实现声卡录音
- 利用DirectSound实现声卡录音
- 利用DirectSound实现声卡录音
- 利用DirectSound实现录音
- 利用DirectSound实现录音
- DirectSound实现录音
- C# 中利用 DirectSound 录音
- DirectX编程:利用 DirectSound 录音
- DirectSound 录音
- DirectSound录音
- DirectX编程:[初级]C# 中利用 DirectSound 录音
- 二十天一学通C#:.NET中文件和文件夹的类
- 对象被持久以后……
- [记录]使用sscanf_s遇到的问题
- 实施敏捷过程中,战胜变化中阻力的6步模型
- 引用System.web和不引用两种方法实现字符串转变为UrlEncode 用于提交POST
- 利用DirectSound实现声卡录音【老毕改版】【Part1】
- SetTimer 方法
- 敏捷软件开发和精益看板管理
- 用ATL开发和部署ActiveX网页控件
- 异地分布式敏捷软件开发 (Distributed Agile Software Development)
- 设置终端(terminal)快捷键
- JS+CSS文章查看系统
- XML和LINQ实战详解
- 需要敏捷,是因为软件开发与交通阻塞相似