使用DirectSound播放MP3文件
将对MP3的支持代码加入到DSound程序中,以供wxDeMPQ使用,随便调整了一下代码,使基类作更多的事情。下面修改后的代码, 源码在这里。
DSoundObject.h
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[ 3 ];
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();
24 virtual int Pause();
25 virtual int Stop();
26 virtual bool IsPlaying() const ;
27 virtual double Duration() = 0 ;
28 protected :
29 virtual int CreateDSound();
30 virtual void ReleaseDSound();
31 virtual int CreateDSoundBuffer();
32 virtual void ReleaseDSoundBuffer();
33
34 virtual int InitDSData() = 0 ;
35 virtual int LoadDSData(DWORD start, DWORD count) = 0 ;
36 virtual int PlayOver();
37 protected :
38 HWND _hWnd;
39 SoundType _eType;
40 IDirectSound * _pDS;
41 IDirectSoundBuffer * _pDSBuffer;
42 IDirectSoundNotify8 * _pDSNotify;
43 protected :
44 int CreateNotifyThread();
45 void ReleaseNotifyThread();
46 static DWORD NotifyHandleProc(LPVOID param);
47 protected :
48 DWORD _dwNotifyThreadID;
49 HANDLE _hNotifyThread;
50
51 DSBPOSITIONNOTIFY _notifyPos[ 2 ];
52 protected :
53 DWORD _dwPlayPos;
54 };
55
56 #endif
DSoundObject.cpp
2 #define __DSOUNDOBJECT_H__
3
4 #include < windows.h >
5 #include < dsound.h >
6
7 #include < string >
8
9 extern HANDLE _eventNotify[ 3 ];
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();
24 virtual int Pause();
25 virtual int Stop();
26 virtual bool IsPlaying() const ;
27 virtual double Duration() = 0 ;
28 protected :
29 virtual int CreateDSound();
30 virtual void ReleaseDSound();
31 virtual int CreateDSoundBuffer();
32 virtual void ReleaseDSoundBuffer();
33
34 virtual int InitDSData() = 0 ;
35 virtual int LoadDSData(DWORD start, DWORD count) = 0 ;
36 virtual int PlayOver();
37 protected :
38 HWND _hWnd;
39 SoundType _eType;
40 IDirectSound * _pDS;
41 IDirectSoundBuffer * _pDSBuffer;
42 IDirectSoundNotify8 * _pDSNotify;
43 protected :
44 int CreateNotifyThread();
45 void ReleaseNotifyThread();
46 static DWORD NotifyHandleProc(LPVOID param);
47 protected :
48 DWORD _dwNotifyThreadID;
49 HANDLE _hNotifyThread;
50
51 DSBPOSITIONNOTIFY _notifyPos[ 2 ];
52 protected :
53 DWORD _dwPlayPos;
54 };
55
56 #endif
1
#include
"
DSoundObject.h
"
2
3 HANDLE _eventNotify[ 3 ];
4
5 CDSoundObject::CDSoundObject(CDSoundObject::SoundType type)
6 : _eType(type)
7 , _pDS(NULL), _pDSBuffer(NULL), _pDSNotify(NULL)
8 , _dwNotifyThreadID( 0 ), _hNotifyThread(NULL)
9 , _dwPlayPos( 0 )
10 {
11 }
12
13 CDSoundObject:: ~ CDSoundObject()
14 {
15 ReleaseNotifyThread();
16 ReleaseDSoundBuffer();
17 ReleaseDSound();
18 }
19
20
21 int CDSoundObject::Init(HWND hwnd)
22 {
23 _hWnd = hwnd;
24
25 return CreateDSound();
26 }
27
28 int CDSoundObject::CreateDSound()
29 {
30 HRESULT hr = DirectSoundCreate(NULL, & _pDS, NULL);
31 if (hr != DS_OK)
32 return - 1 ;
33 _pDS -> SetCooperativeLevel(_hWnd, DSSCL_NORMAL);
34 return 0 ;
35 }
36
37
38 void CDSoundObject::ReleaseDSound()
39 {
40 if (_pDS != NULL)
41 _pDS -> Release(), _pDS = NULL;
42 }
43
44 int CDSoundObject::CreateDSoundBuffer()
45 {
46 ReleaseDSoundBuffer();
47
48 return 0 ;
49 }
50
51 void CDSoundObject::ReleaseDSoundBuffer()
52 {
53 if (_pDSBuffer != NULL)
54 {
55 _pDSBuffer -> Stop();
56 _pDSBuffer -> Release();
57 _pDSBuffer = NULL;
58 }
59 }
60
61 int CDSoundObject::CreateNotifyThread()
62 {
63 ReleaseNotifyThread();
64
65 // event
66 _eventNotify[ 0 ] = CreateEvent(NULL, FALSE, FALSE, NULL);
67 _eventNotify[ 1 ] = CreateEvent(NULL, FALSE, FALSE, NULL);
68 _eventNotify[ 2 ] = CreateEvent(NULL, FALSE, FALSE, NULL);
69
70
71 _hNotifyThread = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NotifyHandleProc, (LPVOID) this , 0 , & _dwNotifyThreadID);
72 if (_hNotifyThread == NULL)
73 return - 1 ;
74
75 HRESULT hr = _pDSBuffer -> QueryInterface(IID_IDirectSoundNotify8, ( void ** ) & _pDSNotify);
76 if (hr != DS_OK)
77 return - 1 ;
78
79 _notifyPos[ 0 ].dwOffset = (SIZE_DS_BUFFER / 2 ) - 1 ;
80 _notifyPos[ 0 ].hEventNotify = _eventNotify[ 0 ];
81 _notifyPos[ 1 ].dwOffset = SIZE_DS_BUFFER - 1 ;
82 _notifyPos[ 1 ].hEventNotify = _eventNotify[ 1 ];
83
84 hr = _pDSNotify -> SetNotificationPositions( 2 , _notifyPos);
85 if (hr != DS_OK)
86 return - 1 ;
87
88 return 0 ;
89 }
90
91 void CDSoundObject::ReleaseNotifyThread()
92 {
93 if (_hNotifyThread != NULL)
94 {
95 // TerminateThread(_hNotifyThread, 0);
96 SetEvent(_eventNotify[ 2 ]);
97 CloseHandle(_hNotifyThread);
98 _hNotifyThread = NULL;
99 }
100 for ( int i = 0 ; i < 2 ; ++ i)
101 {
102 if (_eventNotify[i] != NULL)
103 {
104 CloseHandle(_eventNotify[i]);
105 _eventNotify[i] = NULL;
106 }
107 }
108
109 if (_pDSNotify != NULL)
110 {
111 _pDSNotify -> Release();
112 _pDSNotify = NULL;
113 }
114 }
115
116 DWORD CDSoundObject::NotifyHandleProc(LPVOID param)
117 {
118 CDSoundObject * obj = (CDSoundObject * )(param);
119 if (obj == NULL)
120 return - 1 ;
121
122 while ( true )
123 {
124 DWORD ret = MsgWaitForMultipleObjects( 3 , _eventNotify, FALSE, INFINITE, QS_ALLEVENTS);
125 if (ret == WAIT_FAILED)
126 return - 1 ;
127
128 DWORD notify = ret - WAIT_OBJECT_0;
129 if (notify == 0 )
130 {
131 if (obj -> LoadDSData( 0 , SIZE_DS_BUFFER / 2 ) != 0 )
132 break ;
133 }
134 else if (notify == 1 )
135 {
136 if (obj -> LoadDSData(SIZE_DS_BUFFER / 2 , SIZE_DS_BUFFER / 2 ) != 0 )
137 break ;
138 }
139 else if (notify == 2 )
140 {
141 break ;
142 }
143 else
144 {
145 continue ;
146 }
147 }
148
149 obj -> PlayOver();
150
151 return 0 ;
152 }
153
154 int CDSoundObject::Play()
155 {
156 if (_dwPlayPos == 0 )
157 {
158 InitDSData();
159 }
160
161 _pDSBuffer -> SetCurrentPosition(_dwPlayPos);
162 _pDSBuffer -> SetVolume( - 2000 ); // DSBVOLUME_MAX);
163 _pDSBuffer -> Play( 0 , 0 , DSBPLAY_LOOPING);
164
165 return 0 ;
166 }
167
168 int CDSoundObject::Pause()
169 {
170 if (_pDSBuffer == NULL)
171 return - 1 ;
172 HRESULT hr = _pDSBuffer -> GetCurrentPosition( & _dwPlayPos, NULL);
173 if (hr != DS_OK)
174 return - 1 ;
175 _pDSBuffer -> Stop();
176
177 return 0 ;
178 }
179
180 int CDSoundObject::Stop()
181 {
182 if (_pDSBuffer == NULL)
183 return - 1 ;
184 _pDSBuffer -> Stop();
185 _dwPlayPos = 0 ;
186
187 return 0 ;
188 }
189
190 bool CDSoundObject::IsPlaying() const
191 {
192 if (_pDSBuffer == NULL)
193 return false ;
194
195 DWORD status = 0 ;
196 HRESULT hr = _pDSBuffer -> GetStatus( & status);
197 if (hr != DS_OK)
198 return false ;
199 return ((status & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING ? true : false );
200 }
201
202 int CDSoundObject::PlayOver()
203 {
204 return Stop();
205 }
206
207
DSMP3Object.h
2
3 HANDLE _eventNotify[ 3 ];
4
5 CDSoundObject::CDSoundObject(CDSoundObject::SoundType type)
6 : _eType(type)
7 , _pDS(NULL), _pDSBuffer(NULL), _pDSNotify(NULL)
8 , _dwNotifyThreadID( 0 ), _hNotifyThread(NULL)
9 , _dwPlayPos( 0 )
10 {
11 }
12
13 CDSoundObject:: ~ CDSoundObject()
14 {
15 ReleaseNotifyThread();
16 ReleaseDSoundBuffer();
17 ReleaseDSound();
18 }
19
20
21 int CDSoundObject::Init(HWND hwnd)
22 {
23 _hWnd = hwnd;
24
25 return CreateDSound();
26 }
27
28 int CDSoundObject::CreateDSound()
29 {
30 HRESULT hr = DirectSoundCreate(NULL, & _pDS, NULL);
31 if (hr != DS_OK)
32 return - 1 ;
33 _pDS -> SetCooperativeLevel(_hWnd, DSSCL_NORMAL);
34 return 0 ;
35 }
36
37
38 void CDSoundObject::ReleaseDSound()
39 {
40 if (_pDS != NULL)
41 _pDS -> Release(), _pDS = NULL;
42 }
43
44 int CDSoundObject::CreateDSoundBuffer()
45 {
46 ReleaseDSoundBuffer();
47
48 return 0 ;
49 }
50
51 void CDSoundObject::ReleaseDSoundBuffer()
52 {
53 if (_pDSBuffer != NULL)
54 {
55 _pDSBuffer -> Stop();
56 _pDSBuffer -> Release();
57 _pDSBuffer = NULL;
58 }
59 }
60
61 int CDSoundObject::CreateNotifyThread()
62 {
63 ReleaseNotifyThread();
64
65 // event
66 _eventNotify[ 0 ] = CreateEvent(NULL, FALSE, FALSE, NULL);
67 _eventNotify[ 1 ] = CreateEvent(NULL, FALSE, FALSE, NULL);
68 _eventNotify[ 2 ] = CreateEvent(NULL, FALSE, FALSE, NULL);
69
70
71 _hNotifyThread = CreateThread(NULL, 0 , (LPTHREAD_START_ROUTINE)NotifyHandleProc, (LPVOID) this , 0 , & _dwNotifyThreadID);
72 if (_hNotifyThread == NULL)
73 return - 1 ;
74
75 HRESULT hr = _pDSBuffer -> QueryInterface(IID_IDirectSoundNotify8, ( void ** ) & _pDSNotify);
76 if (hr != DS_OK)
77 return - 1 ;
78
79 _notifyPos[ 0 ].dwOffset = (SIZE_DS_BUFFER / 2 ) - 1 ;
80 _notifyPos[ 0 ].hEventNotify = _eventNotify[ 0 ];
81 _notifyPos[ 1 ].dwOffset = SIZE_DS_BUFFER - 1 ;
82 _notifyPos[ 1 ].hEventNotify = _eventNotify[ 1 ];
83
84 hr = _pDSNotify -> SetNotificationPositions( 2 , _notifyPos);
85 if (hr != DS_OK)
86 return - 1 ;
87
88 return 0 ;
89 }
90
91 void CDSoundObject::ReleaseNotifyThread()
92 {
93 if (_hNotifyThread != NULL)
94 {
95 // TerminateThread(_hNotifyThread, 0);
96 SetEvent(_eventNotify[ 2 ]);
97 CloseHandle(_hNotifyThread);
98 _hNotifyThread = NULL;
99 }
100 for ( int i = 0 ; i < 2 ; ++ i)
101 {
102 if (_eventNotify[i] != NULL)
103 {
104 CloseHandle(_eventNotify[i]);
105 _eventNotify[i] = NULL;
106 }
107 }
108
109 if (_pDSNotify != NULL)
110 {
111 _pDSNotify -> Release();
112 _pDSNotify = NULL;
113 }
114 }
115
116 DWORD CDSoundObject::NotifyHandleProc(LPVOID param)
117 {
118 CDSoundObject * obj = (CDSoundObject * )(param);
119 if (obj == NULL)
120 return - 1 ;
121
122 while ( true )
123 {
124 DWORD ret = MsgWaitForMultipleObjects( 3 , _eventNotify, FALSE, INFINITE, QS_ALLEVENTS);
125 if (ret == WAIT_FAILED)
126 return - 1 ;
127
128 DWORD notify = ret - WAIT_OBJECT_0;
129 if (notify == 0 )
130 {
131 if (obj -> LoadDSData( 0 , SIZE_DS_BUFFER / 2 ) != 0 )
132 break ;
133 }
134 else if (notify == 1 )
135 {
136 if (obj -> LoadDSData(SIZE_DS_BUFFER / 2 , SIZE_DS_BUFFER / 2 ) != 0 )
137 break ;
138 }
139 else if (notify == 2 )
140 {
141 break ;
142 }
143 else
144 {
145 continue ;
146 }
147 }
148
149 obj -> PlayOver();
150
151 return 0 ;
152 }
153
154 int CDSoundObject::Play()
155 {
156 if (_dwPlayPos == 0 )
157 {
158 InitDSData();
159 }
160
161 _pDSBuffer -> SetCurrentPosition(_dwPlayPos);
162 _pDSBuffer -> SetVolume( - 2000 ); // DSBVOLUME_MAX);
163 _pDSBuffer -> Play( 0 , 0 , DSBPLAY_LOOPING);
164
165 return 0 ;
166 }
167
168 int CDSoundObject::Pause()
169 {
170 if (_pDSBuffer == NULL)
171 return - 1 ;
172 HRESULT hr = _pDSBuffer -> GetCurrentPosition( & _dwPlayPos, NULL);
173 if (hr != DS_OK)
174 return - 1 ;
175 _pDSBuffer -> Stop();
176
177 return 0 ;
178 }
179
180 int CDSoundObject::Stop()
181 {
182 if (_pDSBuffer == NULL)
183 return - 1 ;
184 _pDSBuffer -> Stop();
185 _dwPlayPos = 0 ;
186
187 return 0 ;
188 }
189
190 bool CDSoundObject::IsPlaying() const
191 {
192 if (_pDSBuffer == NULL)
193 return false ;
194
195 DWORD status = 0 ;
196 HRESULT hr = _pDSBuffer -> GetStatus( & status);
197 if (hr != DS_OK)
198 return false ;
199 return ((status & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING ? true : false );
200 }
201
202 int CDSoundObject::PlayOver()
203 {
204 return Stop();
205 }
206
207
1
#ifndef __DSMP3OBJECT_H__
2 #define __DSMP3OBJECT_H__
3
4 #include < fstream >
5 #include < string >
6
7 #include " mpg123.h "
8
9 #include " DSoundObject.h "
10
11 class CDSMP3Object : public CDSoundObject
12 {
13 public :
14 CDSMP3Object();
15 virtual ~ CDSMP3Object();
16
17 virtual int LoadFile( const std:: string & file);
18 virtual double Duration();
19 protected :
20 virtual void Release();
21 virtual int CreateDSoundBuffer();
22
23 virtual int InitDSData();
24 virtual int LoadDSData(DWORD start, DWORD count);
25 private :
26 mpg123_handle * _handle;
27 unsigned char _buffer[SIZE_DS_BUFFER / 2 ];
28 WAVEFORMATEX _fmtWave;
29 };
30
31 #endif
32
DSMP3Object.cpp
2 #define __DSMP3OBJECT_H__
3
4 #include < fstream >
5 #include < string >
6
7 #include " mpg123.h "
8
9 #include " DSoundObject.h "
10
11 class CDSMP3Object : public CDSoundObject
12 {
13 public :
14 CDSMP3Object();
15 virtual ~ CDSMP3Object();
16
17 virtual int LoadFile( const std:: string & file);
18 virtual double Duration();
19 protected :
20 virtual void Release();
21 virtual int CreateDSoundBuffer();
22
23 virtual int InitDSData();
24 virtual int LoadDSData(DWORD start, DWORD count);
25 private :
26 mpg123_handle * _handle;
27 unsigned char _buffer[SIZE_DS_BUFFER / 2 ];
28 WAVEFORMATEX _fmtWave;
29 };
30
31 #endif
32
1
#include
"
DSMP3Object.h
"
2
3 CDSMP3Object::CDSMP3Object()
4 : CDSoundObject(CDSoundObject::ST_MP3)
5 , _handle(NULL)
6 {
7 }
8
9 CDSMP3Object:: ~ CDSMP3Object()
10 {
11 Release();
12 }
13
14 void CDSMP3Object::Release()
15 {
16 if (_handle != NULL)
17 {
18 mpg123_close(_handle);
19 mpg123_delete(_handle);
20 _handle = NULL;
21 mpg123_exit();
22 }
23 }
24
25 int CDSMP3Object::LoadFile( const std:: string & file)
26 {
27 Release();
28
29 if (mpg123_init() != MPG123_OK)
30 return - 1 ;
31 int ret = - 1 ;
32 _handle = mpg123_new(NULL, & ret);
33 if (_handle == NULL || ret != MPG123_OK)
34 return - 1 ;
35
36 if (mpg123_open(_handle, file.c_str()) != MPG123_OK)
37 return - 1 ;
38
39 if (CreateDSoundBuffer() != 0 )
40 return - 1 ;
41
42 return 0 ;
43 }
44
45 int CDSMP3Object::CreateDSoundBuffer()
46 {
47 CDSoundObject::CreateDSoundBuffer();
48
49 long rate = 0 ;
50 int channel = 0 ;
51 int encoding = 0 ;
52
53 if (mpg123_getformat(_handle, & rate, & channel, & encoding) != MPG123_OK)
54 return - 1 ;
55 if ((encoding & MPG123_ENC_16) == MPG123_ENC_16)
56 encoding = 16 ;
57 else if ((encoding & MPG123_ENC_32) == MPG123_ENC_32)
58 encoding = 32 ;
59 else
60 encoding = 8 ;
61
62 memset( & _fmtWave, 0 , sizeof (WAVEFORMATEX));
63 _fmtWave.wFormatTag = WAVE_FORMAT_PCM;
64 _fmtWave.nChannels = channel;
65 _fmtWave.nSamplesPerSec = rate;
66 _fmtWave.wBitsPerSample = encoding;
67 _fmtWave.nBlockAlign = encoding / 8 * channel;
68 _fmtWave.nAvgBytesPerSec = rate * (encoding / 8 ) * channel;
69
70 DSBUFFERDESC desc;
71 memset( & desc, 0 , sizeof (DSBUFFERDESC));
72 desc.dwSize = sizeof (DSBUFFERDESC);
73 desc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
74 desc.dwBufferBytes = CDSoundObject::SIZE_DS_BUFFER;
75 desc.lpwfxFormat = & _fmtWave;
76
77 if (_pDSBuffer != NULL)
78 _pDSBuffer -> Release();
79
80 HRESULT hr = _pDS -> CreateSoundBuffer( & desc, & _pDSBuffer, NULL);
81 if (hr != DS_OK)
82 return - 1 ;
83
84 return 0 ;
85 }
86
87 int CDSMP3Object::InitDSData()
88 {
89 // if(mpg123_seek(_handle, 0, SEEK_SET) < 0)
90 // return -1;
91 off_t s = mpg123_seek(_handle, 0 , SEEK_SET);
92 if (s < 0 )
93 return - 1 ;
94
95 if (LoadDSData( 0 , CDSoundObject::SIZE_DS_BUFFER) != 0 )
96 return - 1 ;
97
98 if (CreateNotifyThread() != 0 )
99 return - 1 ;
100
101 // _dwPlayPos = 0;
102
103 return 0 ;
104 }
105
106 int CDSMP3Object::LoadDSData(DWORD start, DWORD count)
107 {
108 LPVOID aptr1 = NULL, aptr2 = NULL;
109 DWORD abyte1 = NULL, abyte2 = NULL;
110
111 HRESULT hr = _pDSBuffer -> Lock(start, count, & aptr1, & abyte1, & aptr2, & abyte2, 0 );
112 if (hr != DS_OK)
113 return - 1 ;
114
115 size_t outsize = 0 ;
116 if (mpg123_read(_handle, _buffer, SIZE_DS_BUFFER / 2 , & outsize) != MPG123_OK)
117 return - 1 ;
118
119 memcpy(aptr1, _buffer, outsize);
120 if (aptr2 != 0 )
121 {
122 if (mpg123_read(_handle, _buffer, SIZE_DS_BUFFER / 2 , & outsize) != MPG123_OK)
123 return - 1 ;
124 memcpy(aptr2, _buffer, outsize);
125 }
126
127 _pDSBuffer -> Unlock(aptr1, abyte1, aptr2, abyte2);
128
129 return 0 ;
130 }
131
132 double CDSMP3Object::Duration()
133 {
134 off_t len = mpg123_length(_handle);
135 return (len / _fmtWave.nSamplesPerSec);
136 }
2
3 CDSMP3Object::CDSMP3Object()
4 : CDSoundObject(CDSoundObject::ST_MP3)
5 , _handle(NULL)
6 {
7 }
8
9 CDSMP3Object:: ~ CDSMP3Object()
10 {
11 Release();
12 }
13
14 void CDSMP3Object::Release()
15 {
16 if (_handle != NULL)
17 {
18 mpg123_close(_handle);
19 mpg123_delete(_handle);
20 _handle = NULL;
21 mpg123_exit();
22 }
23 }
24
25 int CDSMP3Object::LoadFile( const std:: string & file)
26 {
27 Release();
28
29 if (mpg123_init() != MPG123_OK)
30 return - 1 ;
31 int ret = - 1 ;
32 _handle = mpg123_new(NULL, & ret);
33 if (_handle == NULL || ret != MPG123_OK)
34 return - 1 ;
35
36 if (mpg123_open(_handle, file.c_str()) != MPG123_OK)
37 return - 1 ;
38
39 if (CreateDSoundBuffer() != 0 )
40 return - 1 ;
41
42 return 0 ;
43 }
44
45 int CDSMP3Object::CreateDSoundBuffer()
46 {
47 CDSoundObject::CreateDSoundBuffer();
48
49 long rate = 0 ;
50 int channel = 0 ;
51 int encoding = 0 ;
52
53 if (mpg123_getformat(_handle, & rate, & channel, & encoding) != MPG123_OK)
54 return - 1 ;
55 if ((encoding & MPG123_ENC_16) == MPG123_ENC_16)
56 encoding = 16 ;
57 else if ((encoding & MPG123_ENC_32) == MPG123_ENC_32)
58 encoding = 32 ;
59 else
60 encoding = 8 ;
61
62 memset( & _fmtWave, 0 , sizeof (WAVEFORMATEX));
63 _fmtWave.wFormatTag = WAVE_FORMAT_PCM;
64 _fmtWave.nChannels = channel;
65 _fmtWave.nSamplesPerSec = rate;
66 _fmtWave.wBitsPerSample = encoding;
67 _fmtWave.nBlockAlign = encoding / 8 * channel;
68 _fmtWave.nAvgBytesPerSec = rate * (encoding / 8 ) * channel;
69
70 DSBUFFERDESC desc;
71 memset( & desc, 0 , sizeof (DSBUFFERDESC));
72 desc.dwSize = sizeof (DSBUFFERDESC);
73 desc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
74 desc.dwBufferBytes = CDSoundObject::SIZE_DS_BUFFER;
75 desc.lpwfxFormat = & _fmtWave;
76
77 if (_pDSBuffer != NULL)
78 _pDSBuffer -> Release();
79
80 HRESULT hr = _pDS -> CreateSoundBuffer( & desc, & _pDSBuffer, NULL);
81 if (hr != DS_OK)
82 return - 1 ;
83
84 return 0 ;
85 }
86
87 int CDSMP3Object::InitDSData()
88 {
89 // if(mpg123_seek(_handle, 0, SEEK_SET) < 0)
90 // return -1;
91 off_t s = mpg123_seek(_handle, 0 , SEEK_SET);
92 if (s < 0 )
93 return - 1 ;
94
95 if (LoadDSData( 0 , CDSoundObject::SIZE_DS_BUFFER) != 0 )
96 return - 1 ;
97
98 if (CreateNotifyThread() != 0 )
99 return - 1 ;
100
101 // _dwPlayPos = 0;
102
103 return 0 ;
104 }
105
106 int CDSMP3Object::LoadDSData(DWORD start, DWORD count)
107 {
108 LPVOID aptr1 = NULL, aptr2 = NULL;
109 DWORD abyte1 = NULL, abyte2 = NULL;
110
111 HRESULT hr = _pDSBuffer -> Lock(start, count, & aptr1, & abyte1, & aptr2, & abyte2, 0 );
112 if (hr != DS_OK)
113 return - 1 ;
114
115 size_t outsize = 0 ;
116 if (mpg123_read(_handle, _buffer, SIZE_DS_BUFFER / 2 , & outsize) != MPG123_OK)
117 return - 1 ;
118
119 memcpy(aptr1, _buffer, outsize);
120 if (aptr2 != 0 )
121 {
122 if (mpg123_read(_handle, _buffer, SIZE_DS_BUFFER / 2 , & outsize) != MPG123_OK)
123 return - 1 ;
124 memcpy(aptr2, _buffer, outsize);
125 }
126
127 _pDSBuffer -> Unlock(aptr1, abyte1, aptr2, abyte2);
128
129 return 0 ;
130 }
131
132 double CDSMP3Object::Duration()
133 {
134 off_t len = mpg123_length(_handle);
135 return (len / _fmtWave.nSamplesPerSec);
136 }