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

记得老爸说过:天下文人是一家,你抄我来,我抄他。现在来看,写程序亦是如此。 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
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
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
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 }
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库,编译是需要的。