使用DirectSound播放WAVE文件

使用DirectSound播放WAVE文件

    根据 Loveddy上的的资料和源码,写了一个可以播放WAVE文件的程序, 上传。
使用DirectSound播放WAVE文件_第1张图片
    记得老爸说过:天下文人是一家,你抄我来,我抄他。现在来看,写程序亦是如此。 Loveddy的Blog很好,很值得去看,去抄,嘿嘿~
    实际使用DirectSound时,发现对象必须基于一个“窗口”才来使用,即在创建DirectSoundBuffer时,其HWND是必须的,不然虽不会出错,但也没有声音,很奇怪,么找到原因。
    下面是播放的主要部分代码:
    1.对象的基类,因为还要为以后写其他播放对象预留。

 1  #ifndef __DSOUNDOBJECT_H__
 2  #define  __DSOUNDOBJECT_H__
 3 
 4  #include  < dsound.h >
 5 
 6  #include  < string >
 7 
 8 
 9  class  CDSoundObject
10  {
11  public :
12       enum  SoundType { ST_WAVE, ST_MP3 };
13  public :
14      CDSoundObject(SoundType type);
15       virtual   ~ CDSoundObject();
16 
17       virtual   int  Init(HWND hwnd);
18 
19       virtual   int  LoadFile( const  std:: string &  file)  =   0 ;
20 
21  protected :
22       virtual   void  Release();
23 
24       virtual   int  CreateDSound();
25  protected :
26      HWND _hWnd;
27      SoundType _eType;
28      IDirectSound  *  _pDS;
29      IDirectSoundBuffer  *  _pDSBuffer;
30  };
31 
32  #endif

 1  #include  " DSoundObject.h "
 2 
 3  CDSoundObject::CDSoundObject(CDSoundObject::SoundType type)
 4  : _eType(type)
 5  , _pDS(NULL), _pDSBuffer(NULL)
 6  {
 7  }
 8 
 9  CDSoundObject:: ~ CDSoundObject()
10  {
11      Release();
12  }
13 
14  void  CDSoundObject::Release()
15  {
16       if (_pDS  !=  NULL)
17          _pDS -> Release();
18  }
19 
20  int  CDSoundObject::Init(HWND hwnd)
21  {
22      _hWnd  =  hwnd;
23       return  CreateDSound();
24  }
25 
26  int  CDSoundObject::CreateDSound()
27  {
28      HRESULT hr  =  DirectSoundCreate(NULL,  & _pDS, NULL);
29       if (hr  !=  DS_OK)
30           return   - 1 ;
31      _pDS -> SetCooperativeLevel(_hWnd, DSSCL_NORMAL);
32       return   0 ;
33  }

    2.Wave播放对象
 1  #ifndef __DSWAVEOBJECT_H__
 2  #define  __DSWAVEOBJECT_H__
 3 
 4  #include  " DSoundObject.h "
 5 
 6  class  CDSWaveObject :  public  CDSoundObject
 7  {
 8  protected :
 9  //  .WAV file header
10       struct  WAVE_HEADER
11      {
12           char     riff_sig[ 4 ];             //  'RIFF'
13           long     waveform_chunk_size;     //  8
14           char     wave_sig[ 4 ];             //  'WAVE'
15           char     format_sig[ 4 ];           //  'fmt ' (notice space after)
16           long     format_chunk_size;       //  16;
17           short    format_tag;              //  WAVE_FORMAT_PCM
18           short    channels;                //  # of channels
19           long     sample_rate;             //  sampling rate
20           long     bytes_per_sec;           //  bytes per second
21           short    block_align;             //  sample block alignment
22           short    bits_per_sample;         //  bits per second
23           char     data_sig[ 4 ];             //  'data'
24           long     data_size;               //  size of waveform data
25      };
26  public :
27      CDSWaveObject();
28       virtual   ~ CDSWaveObject();
29 
30       virtual   int  LoadFile( const  std:: string &  file);
31       virtual   int  Play();
32       virtual   int  Pause();
33       virtual   int  Stop();
34  protected :
35       virtual   void  Release();
36  protected :
37       int  ReadWaveHeader(std::ifstream &  ifs, WAVE_HEADER &  header)  const ;
38       int  CreateDSBuffer( const  WAVE_HEADER &  header);
39       int  ReadWaveData(std::ifstream &  ifs, size_t start, size_t count);
40  };
41 
42 
43  #endif
  1  #include  < fstream >
  2 
  3  #include  " DSWaveObject.h "
  4 
  5  CDSWaveObject::CDSWaveObject()
  6  : CDSoundObject(CDSoundObject::ST_WAVE)
  7  {
  8  }
  9 
 10  CDSWaveObject:: ~ CDSWaveObject()
 11  {
 12      Release();
 13  }
 14 
 15  void  CDSWaveObject::Release()
 16  {
 17       if (_pDSBuffer  !=  NULL)
 18          _pDSBuffer -> Release();
 19  }
 20 
 21  int  CDSWaveObject::LoadFile( const  std:: string   & file)
 22  {
 23      std::ifstream ifs;
 24      ifs.open(file.c_str(), std::ios:: in   |  std::ios::binary);
 25       if ( ! ifs.is_open())
 26           return   - 1 ;
 27 
 28      WAVE_HEADER header;
 29      memset( & header,  0 sizeof (WAVE_HEADER));
 30 
 31       if (ReadWaveHeader(ifs, header)  !=   0 )
 32           return   - 1 ;
 33 
 34       if (CreateDSBuffer(header)  !=   0 )
 35           return   - 1 ;
 36 
 37       if (ReadWaveData(ifs,  0 , header.data_size)  !=   0 )
 38           return   - 1 ;
 39 
 40      ifs.close();
 41 
 42       return   0 ;
 43  }
 44 
 45  int  CDSWaveObject::ReadWaveHeader(std::ifstream  & ifs, CDSWaveObject::WAVE_HEADER  & header)  const
 46  {
 47      ifs.seekg( 0 , std::ios::beg);
 48      ifs.read(( char * ) & header,  sizeof (WAVE_HEADER));
 49       if ( ! ifs.good())
 50           return   - 1 ;
 51       if (memcmp(header.riff_sig,  " RIFF " 4 ||  memcmp(header.wave_sig,  " WAVE " 4 ||
 52         memcmp(header.format_sig,  " fmt  " 4 ||  memcmp(header.data_sig,  " data " 4 ))
 53      {
 54           return   - 1 ;
 55      }
 56       return   0 ;
 57  }
 58 
 59  int  CDSWaveObject::CreateDSBuffer( const  CDSWaveObject::WAVE_HEADER  & header)
 60  {
 61      WAVEFORMATEX wformat;
 62      memset( & wformat,  0 sizeof (WAVEFORMATEX));
 63      wformat.wFormatTag  =  WAVE_FORMAT_PCM;
 64      wformat.nChannels  =  header.channels;
 65      wformat.nSamplesPerSec  =  header.sample_rate;
 66      wformat.wBitsPerSample  =  header.bits_per_sample;
 67      wformat.nBlockAlign  =  header.bits_per_sample /   8   *  header.channels; //  header.block_align;
 68      wformat.nAvgBytesPerSec  =  header.sample_rate  *  header.block_align; // header.
 69       // wformat.cbSize = header.data_size;
 70 
 71      DSBUFFERDESC desc;
 72      memset( & desc,  0 sizeof (DSBUFFERDESC));
 73      desc.dwSize  =   sizeof (DSBUFFERDESC);
 74      desc.dwFlags  =  DSBCAPS_CTRLVOLUME;
 75      desc.dwBufferBytes  =  header.data_size;
 76      desc.lpwfxFormat  =   & wformat;
 77 
 78       if (_pDSBuffer  !=  NULL)
 79          _pDSBuffer -> Release();
 80 
 81      HRESULT hr  =  _pDS -> CreateSoundBuffer( & desc,  & _pDSBuffer, NULL);
 82       if (hr  !=  DS_OK)
 83           return   - 1 ;
 84       return   0 ;
 85  }
 86 
 87  int  CDSWaveObject::ReadWaveData(std::ifstream  & ifs, size_t start, size_t count)
 88  {
 89      LPVOID aptr1  =  NULL, aptr2  =  NULL;
 90      DWORD abyte1  =  NULL, abyte2  =  NULL;
 91 
 92      HRESULT hr  =  _pDSBuffer -> Lock(start, count,  & aptr1,  & abyte1,  & aptr2,  & abyte2,  0 );
 93       if (hr  !=  DS_OK)
 94           return   - 1 ;
 95      
 96      ifs.read(( char * )aptr1, abyte1);
 97       if (aptr2  !=  NULL)
 98          ifs.read(( char * )aptr2, abyte2);
 99      _pDSBuffer -> Unlock(aptr1, abyte1, aptr2, abyte2);
100 
101       return   0 ;    
102  }
103 
104  int  CDSWaveObject::Play()
105  {
106       if (_pDSBuffer  ==  NULL)
107           return   - 1 ;
108      _pDSBuffer -> SetCurrentPosition( 0 );
109      _pDSBuffer -> SetVolume(DSBVOLUME_MAX);
110      _pDSBuffer -> Play( 0 0 , DSBPLAY_LOOPING);
111 
112       return   0 ;
113  }
114 
115  int  CDSWaveObject::Pause()
116  {
117       return   0 ;
118  }
119 
120  int  CDSWaveObject::Stop()
121  {
122      _pDSBuffer -> Stop();
123       return   0 ;
124  }

    源码工程在这里,写的仓促,仅供参考。使用了wxWidget库,编译是需要的。
   

你可能感兴趣的:(使用DirectSound播放WAVE文件)