directsound的一些基本札记

directsound的一些基本札记

1、配置DirectDound的开发环境
包含以下
#include <mmsystem.h>
#include <dsound.h>
添加Dsound.lib库
comctl32.lib dxerr9.lib winmm.lib dsound.lib dxguid.lib odbc32.lib odbccp32.lib,

2 DiectDound几个对象
 
  创建一个设备对象,后通过设备对象创建缓冲区对象。
  辅助缓冲区由应用程序创建和管理,DirectSound会自动地创建和管理主缓冲区,


3 播放音频文件开发的基本流程

 a 创建一个设备对象,设置设备对象的协作度。

    调用DirectSoundCreat8创建一个支持IDirectSound8接口的对象,
      这个对象通常代表缺省的播放设备。
   
       如果没有声音输出设备,这个函数就返回error,或者,在VXD驱动程序下,
      如果声音输出设备正被某个应用程序通过waveform格式的api函数所控制,
      该函数也返回error。 

LPDIRECTSOUND8 lpDirectSound; 
HRESULT hr 
=  DirectSoundCreate8(NULL, & lpDirectSound, NULL));

      当创建完设备对象后,调用IDirectSound8::SetCooperativeLevel来设置
      协作度,否则听不到声音.

  b.创建一个辅助Buffer,也叫后备缓冲区
      (IDirectSound8::CreateSoundBuffer)
      创建的buffer称作辅助缓冲区,Direcsound通过把几个后备缓冲区的声音
      混合到主缓冲区中,然后输出到声音输出设备上,达到混音的效果。

  c. 获取PCM类型的数据
   
  将WAV文件或者其他资源的数据读取到缓冲区中。

  d. 将数据读取到缓冲区
       其中用到以下来锁缓冲区。
          IDirectSoundBuffer8::Lock
          IDirectSoundBuffer8::Unlock.

  e. 播放缓冲区中的数据
       IDirectSoundBuffer8::Play  播放缓冲区中的音频数据,
       IDirectSoundBuffer8::Stop 暂停播放数据,
       
       获取或者设置正在播放的音频的音量的大小
   IDirectSoundBuffer8::GetVolume
         IDirectSoundBuffer8::SetVolume

      获取设置音频播放的频率
    IDirectSoundBuffer8::GetFrequency
         IDirectSoundBuffer8::SetFrequency   
              主缓冲区的频率不允许改动,

      设置音频在左右声道播放的位置
          IDirectSoundBuffer8::GetPan
          IDirectSoundBuffer8::SetPan

  包含全部音频数据的缓冲区我们称为静态的缓冲区,
        尽管不同的声音可能会反复使用同一个内存buffer,但静态缓冲区的数据只写入一次。

        静态缓冲区只填充一次数据,然后就可以play,
 
  给静态缓冲区加载数据分下面几个步骤
  1、用IDirectSoundBuffer8::Lock函数来锁定所有的内存,
            指定你锁定内存中你开始写入数据的偏移位置,并且取回该偏移位置的地址。
  2、采用标准的数据copy方法,将音频数据复制到返回的地址。
  3、调用IDirectSoundBuffer8::Unlock.,解锁该地址。


用static buffer 播放wav方法

  

 

LPDIRECTSOUNDBUFFER8    g_pDSBuffer8  =  NULL;  // buffer
LPDIRECTSOUND8                   g_pDsd  =  NULL;  // dsound
CWaveFile                                    * 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( " c:\\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();    
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 声音写入到lplockbuf所指地址
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);




   f  流缓冲区播放超大型的wave文件

   流缓冲区就是播放那些比较长的音频文件,边播放,边填充DirectSound缓冲区。

   DirectSound的通知机制
      因为Stream buffer 大小只够容纳一部分数据,在播放完缓冲区中的数据后,
      DirectSound就会通知应用程序,将新的数据填充到DirectSound的缓冲区中。

 

 

#define  MAX_AUDIO_BUF 4                         // 设置4个buffer
#define  BUFFERNOTIFYSIZE 1920                // 每个buffer尺寸为1920

BOOL g_bPlaying     
=  FALSE;                                             // 是否正在播放
LPDIRECTSOUNDNOTIFY8 g_pDSNotify  =  NULL; 
DSBPOSITIONNOTIFY        g_aPosNotify[MAX_AUDIO_BUF];     
// 设置通知标志的数组

HANDLE g_event[MAX_AUDIO_BUF];
for ( int  i  = 0 ; i <  MAX_AUDIO_BUF;i ++ )
{
 g_aPosNotify[i].dwOffset 
=  i *  BUFFERNOTIFYSIZE ;   
    g_aPosNotify[i].hEventNotify 
=  g_event[i];
}

if (FAILED(hr  =  g_pDSBuffer8 -> QueryInterface(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的辅助缓冲区。

 


 

你可能感兴趣的:(directsound的一些基本札记)