• <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方法” 那一段代碼編譯過沒有?代碼好像有問題,沒有聲音。  回復  更多評論
              

            久久国产乱子精品免费女| 久久精品国产日本波多野结衣 | 国产香蕉久久精品综合网| 亚洲国产精品综合久久网络 | 国产AV影片久久久久久| 久久久久亚洲爆乳少妇无| 青青草原综合久久大伊人| 久久精品一区二区三区不卡| 精品99久久aaa一级毛片| 中文国产成人精品久久不卡| 国产成人久久精品一区二区三区| 国产精品嫩草影院久久| 色偷偷久久一区二区三区| 热久久国产欧美一区二区精品| 午夜精品久久久久久久| 久久嫩草影院免费看夜色| 99久久国产综合精品麻豆| 久久久国产亚洲精品| 久久精品国产一区二区三区不卡| 亚洲精品tv久久久久久久久 | 日韩人妻无码精品久久免费一 | 99热精品久久只有精品| 99久久99久久精品国产片果冻| 91久久精品国产91性色也| 日本人妻丰满熟妇久久久久久| 伊人色综合九久久天天蜜桃| 91久久福利国产成人精品| 久久精品国产亚洲AV高清热| 久久妇女高潮几次MBA| 国内精品久久国产| 性做久久久久久久久老女人| 国产精品99久久精品爆乳| 一本一道久久精品综合| 精品久久一区二区三区| 69SEX久久精品国产麻豆| 久久99精品久久久久久久久久| 99久久精品免费看国产一区二区三区 | 一本色道久久88综合日韩精品 | 久久国产免费直播| 国产精品午夜久久| 精品乱码久久久久久夜夜嗨|