• <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>

            Codejie's C++ Space

            Using C++

            更新 - 使用DirectSound播放Wave文件

                修改了一下DSound程序,增加播放Notify,支持播放Buffer。這樣就可以連續播放一個比較大的Wave文件了。源碼在這里。下面是主要的代碼:

                DSoundObject.h
             1 #ifndef __DSOUNDOBJECT_H__
             2 #define __DSOUNDOBJECT_H__
             3 
             4 #include <windows.h>
             5 #include <dsound.h>
             6 
             7 #include <string>
             8 
             9 extern HANDLE _eventNotify[2];//這句很奇怪,如果改成CDSoundObject的static成員,VCExpress鏈接會出錯,不明原因。
            10 
            11 class CDSoundObject
            12 {
            13 public:
            14     enum SoundType { ST_WAVE, ST_MP3 };
            15     static const DWORD SIZE_DS_BUFFER    =    32 * 1024;
            16 public:
            17     CDSoundObject(SoundType type);
            18     virtual ~CDSoundObject();
            19 
            20     virtual int Init(HWND hwnd);
            21     virtual int LoadFile(const std::string& file) = 0;
            22 
            23     virtual int Play() = 0;
            24     virtual int Pause() = 0;
            25     virtual int Stop() = 0;
            26     virtual bool IsPlaying() const = 0;
            27     virtual size_t Duration() const = 0;
            28 protected:
            29     virtual void Release();
            30     virtual int CreateDSound();
            31     virtual int CreateDSoundBuffer();
            32 
            33     virtual int LoadData(DWORD start, DWORD count) = 0;
            34     virtual int PlayOver() = 0;
            35 protected:
            36     HWND _hWnd;
            37     SoundType _eType;
            38     IDirectSound * _pDS;
            39     IDirectSoundBuffer * _pDSBuffer;
            40     IDirectSoundNotify8* _pDSNotify;
            41 protected:
            42     int CreateNotifyThread();
            43     void ReleaseNotifyThread();
            44     static DWORD NotifyHandleProc(LPVOID param);
            45 public:
            46     DWORD _dwNotifyThreadID;
            47     HANDLE _hNotifyThread;
            48 
            49     DSBPOSITIONNOTIFY _notifyPos[2];
            50 };
            51 
            52 #endif

                DSoundObject.cpp
              1 #include "DSoundObject.h"
              2 
              3 HANDLE _eventNotify[2];
              4 
              5 CDSoundObject::CDSoundObject(CDSoundObject::SoundType type)
              6 : _eType(type)
              7 , _pDS(NULL), _pDSBuffer(NULL), _pDSNotify(NULL)
              8 , _dwNotifyThreadID(0), _hNotifyThread(NULL)
              9 {
             10 }
             11 
             12 CDSoundObject::~CDSoundObject()
             13 {
             14     Release();
             15 }
             16 
             17 void CDSoundObject::Release()
             18 {
             19     ReleaseNotifyThread();
             20 
             21     if(_pDS != NULL)
             22         _pDS->Release();
             23 }
             24 
             25 int CDSoundObject::Init(HWND hwnd)
             26 {
             27     _hWnd = hwnd;
             28 
             29     return CreateDSound();
             30 }
             31 
             32 int CDSoundObject::CreateDSound()
             33 {
             34     HRESULT hr = DirectSoundCreate(NULL, &_pDS, NULL);
             35     if(hr != DS_OK)
             36         return -1;
             37     _pDS->SetCooperativeLevel(_hWnd, DSSCL_NORMAL);
             38     return 0;
             39 }
             40 
             41 int CDSoundObject::CreateDSoundBuffer()
             42 {
             43     //if(CreateNotifyThread() != 0)
             44     //    return -1;
             45     return 0;
             46 }
             47 
             48 int CDSoundObject::CreateNotifyThread()
             49 {
             50     //event
             51     _eventNotify[0= CreateEvent(NULL, FALSE, FALSE, NULL);
             52     _eventNotify[1= CreateEvent(NULL, FALSE, FALSE, NULL);
             53 
             54     _hNotifyThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)NotifyHandleProc, (LPVOID)this0&_dwNotifyThreadID);
             55     if(_hNotifyThread == NULL)
             56         return -1;
             57 
             58     HRESULT hr = _pDSBuffer->QueryInterface(IID_IDirectSoundNotify8, (void**)&_pDSNotify);
             59     if(hr != DS_OK)
             60         return -1;
             61 
             62     _notifyPos[0].dwOffset = (SIZE_DS_BUFFER / 2- 1;
             63     _notifyPos[0].hEventNotify = _eventNotify[0];
             64     _notifyPos[1].dwOffset = SIZE_DS_BUFFER - 1;
             65     _notifyPos[1].hEventNotify = _eventNotify[1];
             66 
             67     hr = _pDSNotify->SetNotificationPositions(2, _notifyPos);
             68     if(hr != DS_OK)
             69         return -1;
             70 
             71     return 0;
             72 }
             73 
             74 void CDSoundObject::ReleaseNotifyThread()
             75 {
             76     if(_hNotifyThread != NULL)
             77     {
             78         TerminateThread(_hNotifyThread, 0);
             79         CloseHandle(_hNotifyThread);
             80         _hNotifyThread = NULL;
             81     }
             82     for(int i = 0; i < 2++ i)
             83     {
             84         if(_eventNotify[i] != NULL)
             85         {
             86             CloseHandle(_eventNotify[i]);
             87             _eventNotify[i] = NULL;
             88         }
             89     }
             90 
             91     if(_pDSNotify != NULL)
             92     {
             93         _pDSNotify->Release();
             94         _pDSNotify = NULL;
             95     }
             96 }
             97 
             98 DWORD CDSoundObject::NotifyHandleProc(LPVOID param)
             99 {
            100     CDSoundObject* obj = (CDSoundObject*)(param);
            101     if(obj == NULL)
            102         return -1;
            103 
            104     while(true)
            105     {
            106         DWORD ret = MsgWaitForMultipleObjects(2, _eventNotify, FALSE, INFINITE, QS_ALLEVENTS);
            107         if(ret == WAIT_FAILED)
            108             return -1;
            109         
            110         DWORD notify = ret - WAIT_OBJECT_0;
            111         if(notify == 0)
            112         {
            113             if(obj->LoadData(0, SIZE_DS_BUFFER / 2!= 0)
            114                 break;
            115         }
            116         else if(notify == 1)
            117         {
            118             if(obj->LoadData(SIZE_DS_BUFFER / 2 , SIZE_DS_BUFFER / 2!= 0)
            119                 break;
            120         }
            121         else
            122         {
            123             continue;
            124 //            return -1;
            125         }
            126     }
            127 
            128     obj->PlayOver();
            129 
            130     return 0;
            131 }

                DSWaveObject.h
             1 #ifndef __DSWAVEOBJECT_H__
             2 #define __DSWAVEOBJECT_H__
             3 
             4 #include <fstream>
             5 #include <string>
             6 
             7 #include "DSoundObject.h"
             8 
             9 class CDSWaveObject : public CDSoundObject
            10 {
            11 protected:
            12 // .WAV file header
            13     struct WAVE_HEADER
            14     {
            15         char    riff_sig[4];            // 'RIFF'
            16         long    waveform_chunk_size;    // 8
            17         char    wave_sig[4];            // 'WAVE'
            18         char    format_sig[4];          // 'fmt ' (notice space after)
            19         long    format_chunk_size;      // 16;
            20         short   format_tag;             // WAVE_FORMAT_PCM
            21         short   channels;               // # of channels
            22         long    sample_rate;            // sampling rate
            23         long    bytes_per_sec;          // bytes per second
            24         short   block_align;            // sample block alignment
            25         short   bits_per_sample;        // bits per second
            26         char    data_sig[4];            // 'data'
            27         long    data_size;              // size of waveform data
            28     };
            29 
            30 public:
            31     CDSWaveObject();
            32     virtual ~CDSWaveObject();
            33 
            34     virtual int LoadFile(const std::string& file);
            35     virtual int Play();
            36     virtual int Pause();
            37     virtual int Stop();
            38     virtual bool IsPlaying() const;
            39     virtual size_t Duration() const;
            40 protected:
            41     virtual void Release();
            42 protected:
            43     int LoadWaveData();
            44     int ReadWaveHeader(WAVE_HEADER& header);
            45     int CreateDSBuffer(const WAVE_HEADER& header);
            46 
            47     virtual int LoadData(DWORD start, DWORD count);
            48     virtual int PlayOver();
            49 private:
            50     std::string _strFileName;
            51 
            52     WAVE_HEADER _headerWave;
            53     WAVEFORMATEX _fmtWave;
            54     std::ifstream _ifStream;
            55     DWORD _dwReadSize;
            56     DWORD _dwPlayPos; 
            57 };
            58 
            59 
            60 #endif

                DSWaveObject.cpp
              1 #include "DSWaveObject.h"
              2 
              3 CDSWaveObject::CDSWaveObject()
              4 : CDSoundObject(CDSoundObject::ST_WAVE)
              5 , _dwReadSize(0)
              6 , _dwPlayPos(0)
              7 {
              8 }
              9 
             10 CDSWaveObject::~CDSWaveObject()
             11 {
             12     Release();
             13 }
             14 
             15 void CDSWaveObject::Release()
             16 {
             17     ReleaseNotifyThread();
             18 
             19     if(_pDSBuffer != NULL)
             20     {
             21         _pDSBuffer->Stop();
             22         _pDSBuffer->Release();
             23         _pDSBuffer = NULL;
             24     }
             25     if(_ifStream.is_open())
             26         _ifStream.close();
             27 }
             28 
             29 int CDSWaveObject::LoadFile(const std::string &file)
             30 {
             31     Release();
             32 
             33     _ifStream.open(file.c_str(), std::ios::in | std::ios::binary);
             34     if(!_ifStream.is_open())
             35         return -1;
             36 
             37     memset(&_headerWave, 0sizeof(WAVE_HEADER));
             38 
             39     if(ReadWaveHeader(_headerWave) != 0)
             40         return -1;
             41 
             42     if(CreateDSBuffer(_headerWave) != 0)
             43         return -1;
             44 
             45     return 0;
             46 }
             47 
             48 int CDSWaveObject::LoadWaveData()
             49 {
             50     _dwPlayPos = 0;
             51     _dwReadSize = 0;
             52 
             53     _ifStream.clear();
             54 
             55     _ifStream.seekg(sizeof(WAVE_HEADER), std::ios::beg);
             56     if(LoadData(0, CDSoundObject::SIZE_DS_BUFFER) != 0)
             57     {
             58         return -1;
             59     }
             60 
             61     ReleaseNotifyThread();
             62 
             63     if(CreateNotifyThread() != 0)
             64         return -1;
             65     return 0;
             66 }
             67 
             68 int CDSWaveObject::ReadWaveHeader(CDSWaveObject::WAVE_HEADER &header)
             69 {
             70     _ifStream.seekg(0, std::ios::beg);
             71     _ifStream.read((char*)&header, sizeof(WAVE_HEADER));
             72     if(!_ifStream.good())
             73         return -1;
             74     if(memcmp(header.riff_sig, "RIFF"4|| memcmp(header.wave_sig, "WAVE"4||
             75        memcmp(header.format_sig, "fmt "4|| memcmp(header.data_sig, "data"4))
             76     {
             77         return -1;
             78     }
             79     return 0;
             80 }
             81 
             82 int CDSWaveObject::CreateDSBuffer(const CDSWaveObject::WAVE_HEADER &header)
             83 {
             84 //    WAVEFORMATEX wformat;
             85     memset(&_fmtWave, 0sizeof(WAVEFORMATEX));
             86     _fmtWave.wFormatTag = WAVE_FORMAT_PCM;
             87     _fmtWave.nChannels = header.channels;
             88     _fmtWave.nSamplesPerSec = header.sample_rate;
             89     _fmtWave.wBitsPerSample = header.bits_per_sample;
             90     _fmtWave.nBlockAlign = header.bits_per_sample / 8 * header.channels;// header.block_align;
             91     _fmtWave.nAvgBytesPerSec = header.sample_rate * header.block_align;//header.
             92     //wformat.cbSize = header.data_size;
             93 
             94     DSBUFFERDESC desc;
             95     memset(&desc, 0sizeof(DSBUFFERDESC));
             96     desc.dwSize = sizeof(DSBUFFERDESC);
             97     desc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
             98     desc.dwBufferBytes = CDSoundObject::SIZE_DS_BUFFER;//header.data_size;
             99     desc.lpwfxFormat = &_fmtWave;
            100 
            101     if(_pDSBuffer != NULL)
            102         _pDSBuffer->Release();
            103 
            104     HRESULT hr = _pDS->CreateSoundBuffer(&desc, &_pDSBuffer, NULL);
            105     if(hr != DS_OK)
            106         return -1;
            107     
            108     return 0;
            109 }
            110 
            111 int CDSWaveObject::LoadData(DWORD start, DWORD count)
            112 {
            113     if(!_ifStream.good())
            114         return -1;
            115     if(_dwReadSize >= _headerWave.data_size)
            116         return -1;
            117 
            118     LPVOID aptr1 = NULL, aptr2 = NULL;
            119     DWORD abyte1 = NULL, abyte2 = NULL;
            120 
            121     HRESULT hr = _pDSBuffer->Lock(start, count, &aptr1, &abyte1, &aptr2, &abyte2, 0);
            122     if(hr != DS_OK)
            123         return -1;
            124     
            125     _ifStream.read((char*)aptr1, abyte1);
            126     if(aptr2 != NULL)
            127         _ifStream.read((char*)aptr2, abyte2);
            128 
            129     _pDSBuffer->Unlock(aptr1, abyte1, aptr2, abyte2);
            130 
            131     _dwReadSize += count;
            132 
            133     return 0;
            134 }
            135 
            136 int CDSWaveObject::Play()
            137 {
            138     if(_dwPlayPos == 0)
            139     {
            140         LoadWaveData();
            141     }
            142 
            143     _pDSBuffer->SetCurrentPosition(_dwPlayPos);
            144     _pDSBuffer->SetVolume(-2000);//DSBVOLUME_MAX);
            145     _pDSBuffer->Play(00, DSBPLAY_LOOPING);
            146 
            147     return 0;
            148 }
            149 
            150 int CDSWaveObject::Pause()
            151 {
            152     if(_pDSBuffer == NULL)
            153         return -1;
            154     HRESULT hr = _pDSBuffer->GetCurrentPosition(&_dwPlayPos, NULL);
            155     if(hr != DS_OK)
            156         return -1;
            157     _pDSBuffer->Stop();
            158 
            159     return 0;
            160 }
            161 
            162 int CDSWaveObject::Stop()
            163 {
            164     if(_pDSBuffer == NULL)
            165         return -1;
            166     _pDSBuffer->Stop();
            167     _dwPlayPos = 0;
            168 
            169     return 0;
            170 }
            171 
            172 bool CDSWaveObject::IsPlaying() const
            173 {
            174     if(_pDSBuffer == NULL)
            175         return false;
            176 
            177     DWORD status = 0;
            178     HRESULT hr = _pDSBuffer->GetStatus(&status);
            179     if(hr != DS_OK)
            180         return false;
            181     return ((status & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING ? true : false);
            182 }
            183 
            184 size_t CDSWaveObject::Duration() const
            185 {
            186     return (_headerWave.data_size * 1000 / _fmtWave.nAvgBytesPerSec);
            187     //if(_pDSBuffer == NULL)
            188     //    return 0;
            189     //WAVEFORMATEX wformat;
            190     //HRESULT hr = _pDSBuffer->GetFormat(&wformat, sizeof(WAVEFORMATEX), NULL);
            191     //if(hr != DS_OK)
            192     //    return 0;
            193 
            194     //DSBCAPS caps;
            195     //memset(&caps, 0, sizeof(DSBCAPS));
            196     //caps.dwSize = sizeof(DSBCAPS);
            197     //hr = _pDSBuffer->GetCaps(&caps);
            198     //if(hr != DS_OK)
            199     //    return -1;
            200 
            201     //return (caps.dwBufferBytes * 1000 / wformat.nAvgBytesPerSec);
            202 }
            203 
            204 int CDSWaveObject::PlayOver()
            205 {
            206     return Stop();
            207 }
            208 


            posted on 2009-03-23 22:49 codejie 閱讀(587) 評論(0)  編輯 收藏 引用 所屬分類: C++

            公告

            Using C++

            導航

            統計

            留言簿(73)

            隨筆分類(513)

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            伊人久久无码中文字幕| 国产亚洲精久久久久久无码| 亚洲狠狠婷婷综合久久久久| 久久最新免费视频| 久久噜噜电影你懂的| 久久永久免费人妻精品下载| 97精品伊人久久久大香线蕉 | 国产精品免费看久久久| 久久99久久99精品免视看动漫| 久久久国产一区二区三区| 激情久久久久久久久久| 久久精品国产清自在天天线| 青春久久| 久久久久无码中| 久久亚洲国产精品五月天婷| 亚洲人成无码网站久久99热国产| 亚洲国产成人精品女人久久久 | 欧美久久久久久精选9999| 久久99热这里只有精品国产| 91精品国产色综久久| 三级片免费观看久久| 亚洲精品国精品久久99热一| 99久久超碰中文字幕伊人| 国产精品免费看久久久香蕉| 久久精品国产99久久久香蕉| 色天使久久综合网天天| 69久久夜色精品国产69| 精品无码久久久久久久动漫| 国产69精品久久久久9999APGF | 国产69精品久久久久99| 怡红院日本一道日本久久| 久久午夜福利电影| 精品国产乱码久久久久久1区2区| 99久久精品免费观看国产| 久久久久久国产精品无码下载 | 久久精品人人做人人爽电影蜜月| 国产产无码乱码精品久久鸭| 亚洲国产成人久久综合碰| 久久国产精品一国产精品金尊| 久久亚洲视频| 一级做a爰片久久毛片16|