DirectSound应用程序开发快速入门.doc_第1页
DirectSound应用程序开发快速入门.doc_第2页
DirectSound应用程序开发快速入门.doc_第3页
DirectSound应用程序开发快速入门.doc_第4页
DirectSound应用程序开发快速入门.doc_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

DirectSound应用程序开发快速入门来源: 作者: 出处:巧巧读书 2006-02-06 进入讨论组关 键 词: windowshotmailoperaword程序开发 下一页12摘要:DirectSound编程的入门介绍,通过实例讲解了如何利用DirectSound最基本的功能-播放音频,并提供了DirectSound播放音频文件的两种方式(Static buffer 和Streaming buffer ), 关键词: Directsound stream buffer ,static buffer wave 文件播放一、配置DirectDounf的开发环境在进行DirectSound开发之前,一定要设置好开发环境,否则编译时会提示你很多东西都找不到定义,DirectSound的开发环境很好设置,简单的说就是包含一些头文件,将lib文件添加要工程中。仅仅包含dsound.h肯定是不够的,一般来说,在你的工程中包含下面两个文件就够了。#include #include 如果你还想使用Dsound的API的话,那么你就要在你的vc开发环境中添加Dsound.lib库,如果你的程序还提示有很多的外部链接找不到,那么我建议你可以将下面的库都添加到你的工程中comctl32.lib dxerr9.lib winmm.lib dsound.lib dxguid.lib odbc32.lib odbccp32.lib,这些是我从Dsound提供的例子中得到的,肯定够你用的,如下图开发环境配置好了。你可以在你的工程中任意使用DirectSound提供的接口和函数了。下面简单介绍DirectSound开发中要用到的对象。二、DiectDound几个对象我们首先学习一下Directsound中常用的几个对象,简单学习一下哦DirectSound其实很简单的,主要有下面常用的几个对象。首先,要创建一个设备对象,然后通过设备对象创建缓冲区对象。辅助缓冲区由应用程序创建和管理,DirectSound会自动地创建和管理主缓冲区,一般来说,应用程序即使没有获取这个主缓冲区对象的接口也可以播放音频数据,但是,如果应用程序要想得到IDirectSound3DListener8接口,就必须要自己创建一个主缓冲区。三、播放音频文件开发的基本流程下面我们简单的来学习一下如果通过Directsound的API播放声音,既然是breif overview,那么详细的内容你可以参考下面的一节内容,这里只是简单的介绍一下播放声音的步骤。第一步,创建一个设备对象,设置设备对象的协作度。 在你的代码中你可以通过调用DirectSoundCreat8函数来创建一个支持IDirectSound8接口的对象,这个对象通常代表缺省的播放设备。当然你可以枚举可用的设备,然后将设备的GUID传递给DirectSoundCreat8函数。如果没有声音输出设备,这个函数就返回error,或者,在VXD驱动程序下,如果声音输出设备正被某个应用程序通过waveform格式的api函数所控制,该函数也返回error。下面是创建对象的代码,及其简单LPDIRECTSOUND8 lpDirectSound; HRESULT hr = DirectSoundCreate8(NULL, & lpDirectSound, NULL); 注意,Directsound虽然基于COM,但是你并不需要初始化com库,这些Directsound都帮你做好了,当然,如果你使用DMOs特技,你就要自己初始化com库了,切记。因为Windows是一个多任务操作环境,在同一个时刻有可能多个应用程序共用同一个设备,通过协作水平,DirectX就可以保证这些应用程序在访问设备的时候不会冲突,每个Directsound应用程序都有一个协作度,用来确定来接近设备的程度,当你创建完设备对象后,一定要调用IDirectSound8:SetCooperativeLevel来设置协作度,否则,你不会听到声音的。HRESULT hr = lpDirectSound-SetCooperativeLevel(hwnd, DSSCL_PRIORITY);if (FAILED(hr)ErrorHandler(hr); / Add error-handling here. 第二步,创建一个辅助Buffer,也叫后备缓冲区你可以通过IDirectSound8:CreateSoundBuffer来创建buffer对象,这个对象主要用来获取处理数据,这种buffer称作辅助缓冲区,以和主缓冲区区别开来,Direcsound通过把几个后备缓冲区的声音混合到主缓冲区中,然后输出到声音输出设备上,达到混音的效果。第三步,获取PCM类型的数据将WAV文件或者其他资源的数据读取到缓冲区中。第四步,将数据读取到缓冲区你可以通过 IDirectSoundBuffer8:Lock.方法来准备一个辅助缓冲区来进行写操作,通常这个方法返回一个内存地址,见数据从你的私人buffer中复制到这个地址中,然后调用IDirectSoundBuffer8:Unlock.第五步,播放缓冲区中的数据你可以通过IDirectSoundBuffer8:Play方法来播放缓冲区中的音频数据,你可以通过IDirectSoundBuffer8:Stop来暂停播放数据,你可以反复的莱停止,播放,音频数据,如果你同时创建了几个buffer,那么你就可以同时来播放这些数据,这些声音会自动进行混音的。你可以通过IDirectSoundBuffer8:GetVolume and IDirectSoundBuffer8:SetVolume函数来获取或者设置正在播放的音频的音量的大小。如果设置主缓冲区的音量就会改变声卡的音频的声量大小。音量的大小,用分贝来表示,一般没法来增强缺省的音量,这里要提示一下,分贝的增减不是线形的,减少3分贝相当于减少1/2的能量。最大值衰减100分贝几乎听不到了。通过IDirectSoundBuffer8:GetFrequency and IDirectSoundBuffer8:SetFrequency方法可以获取设置音频播放的频率,主缓冲区的频率不允许改动,通过 IDirectSoundBuffer8:GetPan and IDirectSoundBuffer8:SetPan函数可以设置音频在左右声道播放的位置,具有3D特性的缓冲区没法调整声道。四、使用静态的缓冲区如果我们的wave文件不是很大,那么我们就可以使用静态的缓冲区了。 包含全部音频数据的缓冲区我们称为静态的缓冲区,尽管,不同的声音可能会反复使用同一个内存buffer,但严格来说,静态缓冲区的数据只写入一次。静态缓冲区的创建和管理和流缓冲区很相似,唯一的区别就是它们使用的方式不一样,静态缓冲区只填充一次数据,然后就可以play,然而,流缓冲区是一边play,一边填充数据。给静态缓冲区加载数据分下面几个步骤1、调用IDirectSoundBuffer8:Lock函数来锁定所有的内存,你要指定你锁定内存中你开始写入数据的偏移位置,并且取回该偏移位置的地址。2、采用标准的数据copy方法,将音频数据复制到返回的地址。3、调用IDirectSoundBuffer8:Unlock.,解锁该地址。下面我给出使用static buffer 播放wav文件的完整代码,首先定义我们需要的一些对象:LPDIRECTSOUNDBUFFER8 g_pDSBuffer8 = NULL; /bufferLPDIRECTSOUND8 g_pDsd = NULL; /dsoundCWaveFile *g_pWaveFile= NULL;/下面初始化DirectSound工作。HRESULT hr;if(FAILED(hr = DirectSoundCreate8(NULL,&g_pDsd,NULL)return FALSE;/设置设备的协作度if(FAILED(hr = g_pDsd-SetCooperativeLevel(m_hWnd,DSSCL_PRIORITY)return FALSE;g_pWaveFile = new CWaveFile;g_pWaveFile-Open(_T(d:test.wav),NULL,WAVEFILE_READ);DSBUFFERDESC dsbd;ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );dsbd.dwSize = sizeof(DSBUFFERDESC);dsbd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLFX| DSBCAPS_CTRLPOSITIONNOTIFY |DSBCAPS_GETCURRENTPOSITION2;dsbd.dwBufferBytes = g_pWaveFile-GetSize();/MAX_AUDIO_BUF * BUFFERNOTIFYSIZE ; dsbd.lpwfxFormat = g_pWaveFile-m_pwfx;LPDIRECTSOUNDBUFFER lpbuffer;/创建辅助缓冲区对象if(FAILED(hr = g_pDsd-CreateSoundBuffer(&dsbd,&lpbuffer,NULL)return ;if( FAILED( hr = lpbuffer-QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &g_pDSBuffer8) ) )return ; lpbuffer-Release();/准备工作做完了,下面就开始播放了LPVOID lplockbuf;DWORD len;DWORD dwWrite;g_pDSBuffer8-Lock(0,0,&lplockbuf,&len,NULL,NULL,DSBLOCK_ENTIREBUFFER);g_pWaveFile-Read(BYTE*)lplockbuf,len,&dwWrite);g_pDSBuffer8-Unlock(lplockbuf,len,NULL,0);g_pDSBuffer8-SetCurrentPosition(0);g_pDSBuffer8-Play(0,0,DSBPLAY_LOOPING);五、使用流缓冲区播放超大型的wave文件流缓冲区用来播放那些比较长的音频文件,因为数据比较长,没法一次填充到缓冲区中,一边播放,一边将新的数据填充到DirectSound的缓冲区中。可以通过IDirectSoundBuffer8:Play函授来播放缓冲区中的内容,注意在该函数的参数中一定要设置DSBPLAY_LOOPING标志。通过IDirectSoundBuffer8:Stop方法中断播放,该方法会立即停止缓冲区播放,因此你要确保所有的数据都被播放,你可以通过拖动播放位置或者设置通知位置来实现。将音频流倒入缓冲区需要下面三个步骤1、确保你的缓冲区已经做好接收新数据的准备。你可以拖放播放的光标位置或者等待通知2、调用IDirectSoundBuffer8:Lock.函数锁住缓冲区的位置,这个函数返回一个或者两个可以写入数据的地址3、使用标准的copy数据的方法将音频数据写入缓冲区中4、IDirectSoundBuffer8:Unlock.,解锁这里我要讲一下DirectSound的通知机制。因为Stream buffer 大小只够容纳一部分数据,因此,在播放完缓冲区中的数据后,DirectSound就会通知应用程序,将新的数据填充到DirectSound的缓冲区中。假如我们设置DirectSound的buffersize 为1920*4,如下图我们可以给DirectSound设置一个事件,并且设置buffer通知大小,如下:HANDLE g_eventMAX_AUDIO_BUF;for(int i =0; iQueryInterface(IID_IDirectSoundNotify,(LPVOID *) &g_pDSNotify )return ;g_pDSNotify-SetNotificationPositions(MAX_AUDIO_BUF,g_aPosNotify);g_pDSNotify-Release();当DirectSound播放到buffer的1920,3840,5760,7680等位置时,Directsound就会通知应用程序,将g_ event,设置为通知态,应用程序就可以通过WaitForMultipleObjects 函数等待DirectSound的通知,将数据填充到DirectSoun的辅助缓冲区。下面我给出Stream buffer 播放wave文件的代码。#define MAX_AUDIO_BUF 4#define BUFFERNOTIFYSIZE 1920LPDIRECTSOUNDBUFFER8 g_pDSBuffer8 = NULL; /bufferLPDIRECTSOUND8 g_pDsd = NULL; /dsoundCWaveFile *g_pWaveFile= NULL;BOOL g_bPlaying = FALSE; /是否正在播放LPDIRECTSOUNDNOTIFY8 g_pDSNotify = NULL; DSBPOSITIONNOTIFY g_aPosNotifyMAX_AUDIO_BUF;/设置通知标志的数组HANDLE g_eventMAX_AUDIO_BUF;DWORD g_dwNextWriteOffset = 0;/初始化DirectSoundHRESULT hr;if(FAILED(hr = DirectSoundCreate8(NULL,&g_pDsd,NULL)return FALSE;if(FAILED(hr = g_pDsd-SetCooperativeLevel(m_hWnd,DSSCL_PRIORITY)return FALSE;g_pWaveFile = new CWaveFile;g_pWaveFile-Open(_T(d:test.wav),NULL,WAVEFILE_READ);DSBUFFERDESC dsbd;ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );dsbd.dwSize = sizeof(DSBUFFERDESC);dsbd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY |DSBCAPS_GETCURRENTPOSITION2;dsbd.dwBufferBytes = MAX_AUDIO_BUF * BUFFERNOTIFYSIZE ; dsbd.lpwfxFormat = g_pWaveFile-m_pwfx;LPDIRECTSOUNDBUFFER lpbuffer;/创建DirectSound辅助缓冲区if(FAILED(hr = g_pDsd-CreateSoundBuffer(&dsbd,&lpbuffer,NULL)return FALSE;if( FAILED( hr = lpbuffer-QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &g_pDSBuffer8) ) )return FALSE; lpbuffer-Release();/设置DirectSound通知 机制for(int i =0; iQueryInterface(IID_IDirectSoundNotify,(LPVOID*) g_pDSNotify )return ;g_pDSNotify-SetNotificationPositions(MAX_AUDIO_BUF,g_aPosNotify);g_pDSNotify-Release();ok,在下面的play函数中,我们就要单独启动一个线程,来播放了void OnBnClickedButtonPlay()g_bPlaying =TRUE;g_pWaveFile-ResetFile();CreateThread(0,0,PlayThread,this,NULL,NULL);/停止播放音频void CDsoundEffectDemoDlg:OnBnClickedButtonStop()/ TODO: 在此添加控件通知处理程序代码g_bPlaying =FALSE; Sleep(500);g_pDSBuffer8-Stop();下面我们看看我们的播放线程,在线程里,我们首先将音频数据填充到DirectSound的辅助缓冲区中,然后调用DirectSound buffer 的play方法,开始播放,然后就在WaitForMultipleObjects 等待DirectSound的通知吧,然后读取wave文件将数据填充到DirectSound的空buffer中。DWORD WINAPI PlayThread(LPVOID lpParame)DWORD res;LPVOID lplockbuf;DWORD len;DWORD dwWrite;g_pDSBuffer8-Lock(0,0,&lplockbuf,&len,NULL,NULL,DSBLOCK_ENTIREBUFFER);g_pWaveFile-Read(BYTE*)lplockbuf,len,&dwWrite);g_pDSBuffer8-Unlock(lplockbuf,len,NULL,0);g_pDSBuffer8-SetCurrentPosition(0);g_pDSBuffer8-Play(0,0,DSBPLAY_LOOPING);g_dwNextWriteOffset = 0;while(g_bPlaying)res = WaitForMultipleObjects (MAX_AUDIO_BUF, g_event, FALSE, INFINITE);if(res WAIT_OBJECT_0) ProcessBuffer();return 0;下面的函数主要是给空的DirectSound缓冲区填充 音频数据。void ProcessBuffer()DWORD dwBytesWrittenToBuffer = 0;VOID* pDSLockedBuffer = NULL;VOID* pDSLockedBuffer2 = NULL;DWORD dwDSLockedBufferSize;DWORD dwDSLockedBufferSize2;HRESULT hr; g_pDSBuffer8-Lock(g_dwNextWriteOffset,BUFFERNOTIFYSIZE,&pDSLockedBuffer,&dwDSLockedBufferSize, &pDSLockedBuffer2,&dwDS

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论