DirectSound 播放 录音

// DirectSoundDlg.cpp : 实现文件

//

 

#include "stdafx.h"

#include "DirectSound.h"

#include "DirectSoundDlg.h"

 

#include <process.h>

 

#include <mmsystem.h>

#include <dsound.h>

 

//#pragma comment(lib,"dxerr9.lib")

#pragma comment(lib,"winmm.lib")

#pragma comment(lib,"dsound.lib")

#pragma comment(lib,"dxguid.lib")

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

 

 

// CDirectSoundDlg 对话框

/***************************************/

 

LPDIRECTSOUND8 ds=NULL;

LPDIRECTSOUNDBUFFER8 dsb=NULL;

 

/***************************************/

 

 

 

CDirectSoundDlg::CDirectSoundDlg(CWnd* pParent /*=NULL*/)

: CDialog(CDirectSoundDlg::IDD, pParent)

{

m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

}

 

void CDirectSoundDlg::DoDataExchange(CDataExchange* pDX)

{

CDialog::DoDataExchange(pDX);

}

 

BEGIN_MESSAGE_MAP(CDirectSoundDlg, CDialog)

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

//}}AFX_MSG_MAP

ON_BN_CLICKED(IDC_BUTTON1, &CDirectSoundDlg::OnBnClickedButton1)

ON_BN_CLICKED(IDC_BUTTON3, &CDirectSoundDlg::OnBnClickedButton3)

ON_BN_CLICKED(IDC_BUTTON2, &CDirectSoundDlg::OnBnClickedButton2)

END_MESSAGE_MAP()

 

 

// CDirectSoundDlg 消息处理程序

LRESULT ret;

CFile wavefile;

typedef struct   

{   

   DWORD   dwRiff;     // Type of file header.    

   DWORD   dwSize;     // Size of file header.    

   DWORD   dwWave;     // Type of wave.    

} RIFF_FILEHEADER, *PRIFF_FILEHEADER;   

 

 

// -----------------------------------------------------------------------------    

//                              ChunkHeader    

// -----------------------------------------------------------------------------    

typedef struct   

{   

   DWORD   dwCKID;        // Type Identification for current chunk header.    

   DWORD   dwSize;        // Size of current chunk header.    

} RIFF_CHUNKHEADER, *PRIFF_CHUNKHEADER;   

 

 

BOOL CDirectSoundDlg::OnInitDialog()

{

CDialog::OnInitDialog();

 

// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动

//  执行此操作

SetIcon(m_hIcon, TRUE); // 设置大图标

SetIcon(m_hIcon, FALSE); // 设置小图标

 

// TODO: 在此添加额外的初始化代码

 

 

return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE

}

 

// 如果向对话框添加最小化按钮,则需要下面的代码

//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,

//  这将由框架自动完成。

 

void CDirectSoundDlg::OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // 用于绘制的设备上下文

 

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

 

// 使图标在工作区矩形中居中

int cxIcon = GetSystemMetrics(SM_CXICON);

int cyIcon = GetSystemMetrics(SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect.Width() - cxIcon + 1) / 2;

int y = (rect.Height() - cyIcon + 1) / 2;

 

// 绘制图标

dc.DrawIcon(x, y, m_hIcon);

}

else

{

CDialog::OnPaint();

}

}

 

//当用户拖动最小化窗口时系统调用此函数取得光标

//显示。

HCURSOR CDirectSoundDlg::OnQueryDragIcon()

{

return static_cast<HCURSOR>(m_hIcon);

}

 

 

void CDirectSoundDlg::OnBnClickedButton1()

{

// TODO: 在此添加控件通知处理程序代码

WAVEFORMATEX pWFX;

pWFX.cbSize=0;

pWFX.wFormatTag=WAVE_FORMAT_PCM;

pWFX.nChannels=1;

pWFX.nSamplesPerSec=8000;

pWFX.wBitsPerSample=16;

pWFX.nAvgBytesPerSec = pWFX.nChannels * pWFX.nSamplesPerSec * pWFX.wBitsPerSample / 8;

pWFX.nBlockAlign =pWFX.wBitsPerSample * pWFX.nChannels / 8;

 

wavefile.Open(L"C://r.data",CFile::modeRead);

if(wavefile.m_hFile==CFile::hFileNull)

{

AfxMessageBox(L"没有找到c://r.data/n程序终止");

ExitProcess(0);

}

DWORD waveBufferSize=wavefile.GetLength();//-(sizeof(RIFF_FILEHEADER)+sizeof(RIFF_CHUNKHEADER)*2+sizeof(WAVEFORMATEX));

 

ret=DirectSoundCreate8(NULL,&ds,NULL);

if(FAILED(ret))

{

AfxMessageBox(L"初始化DirectSound失败");

ExitProcess(0);

}

ret=ds->SetCooperativeLevel(this->m_hWnd,DSSCL_PRIORITY);

DSBUFFERDESC csdd;

ZeroMemory(&csdd,sizeof(DSBUFFERDESC));

csdd.lpwfxFormat=&pWFX;

csdd.dwFlags=DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLFX| DSBCAPS_CTRLPOSITIONNOTIFY |DSBCAPS_GETCURRENTPOSITION2;

csdd.dwSize=sizeof(DSBUFFERDESC);

csdd.dwBufferBytes=waveBufferSize;

LPDIRECTSOUNDBUFFER  pbuffer=NULL;

ret=ds->CreateSoundBuffer(&csdd,&pbuffer,NULL);

if(FAILED(ret))

{

AfxMessageBox(L"CreateSoundBuffer失败");

if(wavefile.m_hFile!=CFile::hFileNull)

wavefile.Close();

ds->Release();

ExitProcess(0);

}

ret=pbuffer->QueryInterface(IID_IDirectSoundBuffer8,(LPVOID*)&dsb);

if(FAILED(ret))

{

AfxMessageBox(L"CreateSoundBuffer失败");

if(wavefile.m_hFile!=CFile::hFileNull)

wavefile.Close();

ds->Release();

pbuffer->Release();

 

ExitProcess(0);

}

pbuffer->Release();

 

 

LPVOID data;

DWORD len;

DWORD writtenBytes;

ret=dsb->Lock(0,0,&data,&len,NULL,NULL,DSBLOCK_ENTIREBUFFER);

wavefile.Seek(0,CFile::begin);

writtenBytes=wavefile.Read(data,len);

ret=dsb->Unlock(data,len,NULL,NULL);

dsb->SetCurrentPosition(0);

ret=dsb->Play(0,0,0);

wavefile.Close();

 

}

 

void CDirectSoundDlg::OnClose()

{

wavefile.Close();

dsb->Release();

ds->Release();

}

 

 

#define NOTIFYS 10

#define NOTIFYSIZE 10240

 

LPDIRECTSOUNDCAPTURE8 g_dsc=NULL;

LPDIRECTSOUNDCAPTUREBUFFER8 g_dscb=NULL;

LPDIRECTSOUNDNOTIFY g_dsn=NULL;

 

 

DSBPOSITIONNOTIFY pn[NOTIFYS];

HANDLE hNotify[NOTIFYS];

DWORD iBufferSize;

 

 

FILE* f;

 

BOOL quit=FALSE;

DWORD _stdcall RecordNotify(void*)

{

DWORD r;

f=fopen("c://r.data","wb");

DWORD readpos;

LPVOID pb1,pb2;

DWORD pd1,pd2;

int locksize=0;

int iBufferOffset=0;

if(!f)

{

MessageBox(NULL,L"创建文件失败",L"",0);

return 0;

}

while(!quit)

{

/*if(r==WAIT_OBJECT_0+0)

{

 

if(SUCCEEDED(g_dscb->GetCurrentPosition(NULL,&cur)))

{

if(SUCCEEDED(g_dscb->Lock(0,bufferSize/2,&pb1,&pd1,NULL,NULL,0)))

{

fwrite(pb1,sizeof(char),pd1,f);

fflush(f);

}

g_dscb->Unlock(pb1,pd1,NULL,NULL);

}

}

else if(r==WAIT_OBJECT_0 + 1)

{

if(SUCCEEDED(g_dscb->GetCurrentPosition(NULL,&cur)))

{

if(SUCCEEDED(g_dscb->Lock(cur,bufferSize/2,&pb1,&pd1,NULL,NULL,0)))

{

fwrite(pb1,sizeof(char),pd1,f);

fflush(f);

}

g_dscb->Unlock(pb1,pd1,NULL,NULL);

}

 

 

}*/

WAIT_FAILED != (r=WaitForMultipleObjects(NOTIFYS,hNotify,FALSE,INFINITE));

if(quit)

break;

if(SUCCEEDED(g_dscb->GetCurrentPosition(NULL,&readpos)))

{

locksize = readpos - iBufferOffset;//这个大小就是我们可以安全读取的大小

if(locksize!=0)

{

if (locksize < 0)

{//因为我们是循环的使用缓冲区,所以有一种情况下为负:当文以载读指针回到第一个通知点,而Ibuffeoffset还在最后一个通知处

locksize += iBufferSize;

}

 

if(SUCCEEDED(g_dscb->Lock(iBufferOffset,locksize,&pb1,&pd1,NULL,NULL,0)))

{

fwrite(pb1,sizeof(char),pd1,f);

g_dscb->Unlock(pb1,pd1,NULL,NULL);

fflush(f);

}

iBufferOffset += pd1;

iBufferOffset %= iBufferSize;//取模是因为缓冲区是循环的。

}

}

 

}

fclose(f);

}

 

//LPDIRECTSOUND8 g_ds=NULL;

 

void CDirectSoundDlg::OnBnClickedButton3()

{

// TODO: 在此添加控件通知处理程序代码

ret=DirectSoundCaptureCreate8(NULL,&g_dsc,NULL);

if(FAILED(ret))

{

AfxMessageBox(_T("DirectSoundCreate8失败"));

return ;

}

DSCBUFFERDESC desc;

WAVEFORMATEX wfx;

wfx.cbSize=sizeof(WAVEFORMATEX);

wfx.nChannels=1;

wfx.nSamplesPerSec=8000;

wfx.wFormatTag=WAVE_FORMAT_PCM;

wfx.wBitsPerSample=16;

wfx.nBlockAlign=2;

wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;

 

ZeroMemory(&desc,sizeof(DSCBUFFERDESC));

desc.dwSize=sizeof(DSCBUFFERDESC);

desc.lpwfxFormat=&wfx;

desc.dwBufferBytes=iBufferSize=NOTIFYS*NOTIFYSIZE;

desc.dwFlags=0;

desc.lpDSCFXDesc=NULL;

 

LPDIRECTSOUNDCAPTUREBUFFER lpBuffer;

ret=g_dsc->CreateCaptureBuffer(&desc,&lpBuffer,NULL);

if(FAILED(ret))

{

AfxMessageBox(_T("创建Buffer失败"));

g_dsc->Release();

return ;

}

ret=lpBuffer->QueryInterface(IID_IDirectSoundCaptureBuffer8,(LPVOID*)&g_dscb);

if(FAILED(ret))

{

AfxMessageBox(_T("创建Buffer8失败"));

lpBuffer->Release();

g_dsc->Release();

}

lpBuffer->Release();

ret=g_dscb->QueryInterface(IID_IDirectSoundNotify,(LPVOID*)&g_dsn);

 

/*pn[0].dwOffset=bufferSize/2;

pn[0].hEventNotify=hNotify[0]=CreateEvent(NULL,FALSE,FALSE,NULL);

 

pn[1].dwOffset=DSBPN_OFFSETSTOP;

pn[1].hEventNotify=hNotify[1]=CreateEvent(NULL,FALSE,FALSE,NULL);*/

for(int i=0;i<NOTIFYS;i++)

{

pn[i].dwOffset=NOTIFYSIZE+i*NOTIFYSIZE-1;

pn[i].hEventNotify=hNotify[i]=CreateEvent(NULL,FALSE,FALSE,NULL);

 

}

 

if(SUCCEEDED(ret))

{

ret=g_dsn->SetNotificationPositions(NOTIFYS,pn);

if(FAILED(ret))

{

AfxMessageBox(_T("创建Notify失败"));

 

}

else

{

CreateThread(NULL,0,RecordNotify,NULL,0,NULL);

//_beginthread(RecordNotify,0,NULL);

}

g_dsn->Release();

ret=g_dscb->Start(DSCBSTART_LOOPING);

if(FAILED(ret))

{

AfxMessageBox(L"录音失败");

}

}else

{

AfxMessageBox(_T("QueryInterface失败"));

 

}

 

 

}

 

void CDirectSoundDlg::OnBnClickedButton2()

{

// TODO: 在此添加控件通知处理程序代码

if(g_dscb)

{

g_dscb->Stop();

quit=TRUE;

SetEvent(hNotify[0]);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值