• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            kenlistian

            厚積薄發. 勤為槳,思為帆

               :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理 ::
              73 隨筆 :: 4 文章 :: 22 評論 :: 0 Trackbacks

            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的輔助緩沖區。

             


             

            posted on 2008-12-27 18:30 kenlistian 閱讀(2921) 評論(1)  編輯 收藏 引用 所屬分類: directx

            評論

            # re: directsound的一些基本札記 2009-02-25 12:17 Ian
            請問主人“用static buffer 播放wav方法” 那一段代碼編譯過沒有?代碼好像有問題,沒有聲音。  回復  更多評論
              

            蜜桃麻豆WWW久久囤产精品| 久久婷婷五月综合国产尤物app| 欧洲人妻丰满av无码久久不卡| 午夜天堂精品久久久久| 日韩人妻无码精品久久免费一| 精品一区二区久久| 久久人人爽人人爽人人片AV麻豆 | …久久精品99久久香蕉国产| 久久久九九有精品国产| 午夜精品久久久久久久无码| 午夜精品久久久久久久| 国产L精品国产亚洲区久久| 精品久久久久成人码免费动漫 | 一本一道久久精品综合| 伊人精品久久久久7777| 久久综合狠狠色综合伊人| 精品久久久久久久国产潘金莲| 一本大道加勒比久久综合| 伊人久久大香线蕉亚洲五月天| 久久久WWW成人| 久久综合狠狠综合久久激情 | 亚洲va久久久噜噜噜久久| 一级女性全黄久久生活片免费 | 色综合久久综合中文综合网| 精品视频久久久久| 99久久婷婷国产一区二区| 日韩AV无码久久一区二区| 中文国产成人精品久久亚洲精品AⅤ无码精品| 色综合久久无码五十路人妻| 久久国产劲爆AV内射—百度| 久久久久国产精品三级网| 日本一区精品久久久久影院| 国产精品久久久久jk制服| 亚洲AV无码1区2区久久| 午夜精品久久久久久久| 天堂久久天堂AV色综合| 久久精品中文无码资源站| 精品乱码久久久久久久| 久久久久99精品成人片直播| 久久综合精品国产二区无码| 久久亚洲精品成人av无码网站|