]> git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia/sndsnd.cpp
3422b7249f8ab5a4f0b66471b0b17cbe3e651ca5
[wxWidgets.git] / utils / wxMMedia / sndsnd.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 // Name: sndsnd.cpp
3 // Purpose: wxMMedia
4 // Author: Guilhem Lavaux
5 // Created: 1997
6 // Updated: 1998
7 // Copyright: (C) 1997, 1998, Guilhem Lavaux
8 // License: wxWindows license
9 ////////////////////////////////////////////////////////////////////////////////
10 #ifdef __GNUG__
11 #pragma implementation "sndsnd.h"
12 #endif
13 #ifdef WX_PRECOMP
14 #include "wx_prec.h"
15 #else
16 #include "wx/wx.h"
17 #endif
18 #include "sndsnd.h"
19 #include "sndfrmt.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #define PROCESS_EVENT() wxYield()
26 // #define PROCESS_EVENT()
27
28 // ----------------------------------------------------------------------------
29 // wxSndBuffer: base sound buffer class
30 // ----------------------------------------------------------------------------
31
32
33 wxSndBuffer::wxSndBuffer()
34 : m_sndmode(wxSND_OUTPUT), m_sndflags(0), m_sndoutput(NULL), m_sndcodec(NULL)
35 {
36 }
37
38 wxSndBuffer::~wxSndBuffer()
39 {
40 }
41
42 void wxSndBuffer::Set(wxSndFlags flags)
43 {
44 m_sndflags |= flags;
45
46 if ((m_sndflags & wxSND_BUFAUTO) && (flags & wxSND_BUFREADY))
47 m_sndoutput->QueueBuffer(*this);
48 }
49
50 void wxSndBuffer::SetError(wxSndError error)
51 {
52 if (error == wxSND_NOERROR)
53 Clear(wxSND_BUFERR);
54 else
55 Set(wxSND_BUFERR);
56
57 m_snderror = error;
58 }
59
60 wxSndError wxSndBuffer::GetError()
61 {
62 if (IsNotSet(wxSND_BUFERR))
63 return wxSND_NOERROR;
64 Clear(wxSND_BUFERR);
65 return m_snderror;
66 }
67
68 void wxSndBuffer::OnPlayFinished()
69 {
70 }
71
72 void wxSndBuffer::OnBufferOutFinished()
73 {
74 }
75
76 void wxSndBuffer::OnBufferInFinished(char *WXUNUSED(iobuf),
77 wxUint32& WXUNUSED(size))
78 {
79 }
80
81 bool wxSndBuffer::Wait()
82 {
83 if (IsNotSet(wxSND_BUFLOCKED))
84 return FALSE;
85
86 while (IsSet(wxSND_BUFLOCKED))
87 PROCESS_EVENT();
88
89 return IsNotSet(wxSND_BUFERR);
90 }
91
92 void wxSndBuffer::HardLock()
93 {
94 m_mutex.Lock();
95 }
96
97 void wxSndBuffer::HardUnlock()
98 {
99 m_mutex.Unlock();
100 }
101
102 void wxSndBuffer::ChangeCodec(int no)
103 {
104 wxDELETE(m_sndcodec);
105
106 m_sndformat.SetCodecNo(no);
107 m_sndcodec = m_sndformat.GetCodec();
108 m_sndcodec->SetIOBuffer(this);
109 }
110
111 // ----------------------------------------------------------------------------
112 // wxSndSimpleBuffer: the simplest sound buffer
113 // ----------------------------------------------------------------------------
114
115
116 wxSndSimpleBuffer::wxSndSimpleBuffer(char *buffer, wxUint32 bufsize,
117 wxSndMode mode)
118 : wxSndBuffer()
119 {
120 m_sndbuf = buffer;
121 m_sndsize = bufsize;
122 m_sndmode = mode;
123
124 m_sndptr = 0;
125 }
126
127 wxSndSimpleBuffer::~wxSndSimpleBuffer()
128 {
129 }
130
131 void wxSndSimpleBuffer::OnNeedOutputData(char *iobuf, wxUint32& size)
132 {
133 char *buf = m_sndbuf + m_sndptr;
134 wxUint32 nbdata_left = m_sndsize - m_sndptr;
135
136 if (m_sndptr >= m_sndsize) {
137 size = 0;
138 return;
139 }
140
141 if (size > nbdata_left)
142 size = nbdata_left;
143
144 m_sndptr += size;
145
146 memcpy(iobuf, buf, size);
147 }
148
149 void wxSndSimpleBuffer::OnBufferOutFinished()
150 {
151 if (m_sndptr >= m_sndsize)
152 OnPlayFinished();
153 }
154
155 void wxSndSimpleBuffer::OnBufferInFinished(char *iobuf, wxUint32& size)
156 {
157 char *raw_buf = m_sndbuf + m_sndptr;
158 wxUint32 data_left = m_sndsize - m_sndptr;
159
160 if (!data_left) {
161 size = 0;
162 return;
163 }
164
165 if (size > data_left)
166 size = data_left;
167
168 memcpy(raw_buf, iobuf, size);
169 m_sndptr += size;
170 }
171
172 void wxSndSimpleBuffer::SetData(char *buffer, wxUint32 bufsize,
173 wxSndMode mode)
174 {
175 m_sndbuf = buffer;
176 m_sndsize = bufsize;
177 m_sndmode = mode;
178 }
179
180 bool wxSndSimpleBuffer::RestartBuffer(wxSndMode mode)
181 {
182 m_sndptr = 0;
183 return TRUE;
184 }
185
186 wxUint32 wxSndSimpleBuffer::GetSize() const
187 {
188 return m_sndsize;
189 }
190
191 wxUint32 wxSndSimpleBuffer::Available() const
192 {
193 return m_sndsize - m_sndptr;
194 }
195
196 // ----------------------------------------------------------------------------
197 // wxSound: base sound driver implementation
198 // ----------------------------------------------------------------------------
199
200 wxSound::wxSound()
201 : wxObject(),
202 m_lastbuf(NULL), m_sndcbk(NULL), m_snderror(wxSND_NOERROR)
203 {
204 m_buffers.Clear();
205 }
206
207 wxSound::~wxSound()
208 {
209 wxNode *node = m_buffers.First();
210
211 while (node) {
212 wxSndBuffer *buf = (wxSndBuffer *)node->Data();
213
214 buf->Clear(wxSND_BUFLOCKED);
215 }
216 }
217
218 bool wxSound::QueueBuffer(wxSndBuffer& buf)
219 {
220 if (buf.IsSet(wxSND_BUFLOCKED) || buf.IsNotSet(wxSND_BUFREADY))
221 return FALSE;
222
223 buf.Set(wxSND_BUFLOCKED);
224 buf.SetOutput(*this);
225
226 m_buffers.Append(&buf);
227 return Wakeup(buf);
228 }
229
230 bool wxSound::UnqueueBuffer(wxSndBuffer& buf)
231 {
232 wxNode *node;
233
234 if (buf.IsNotSet(wxSND_BUFLOCKED))
235 return FALSE;
236
237 node = m_buffers.Member(&buf);
238 if (!node)
239 return FALSE;
240
241 StopBuffer(buf);
242 node = m_buffers.Member(&buf);
243 if (node)
244 delete node;
245
246 return TRUE;
247 }
248
249 void wxSound::Callback(wxSndCallback cbk)
250 {
251 m_sndcbk = cbk;
252 }
253
254 void wxSound::SetClientData(char *cdata)
255 {
256 m_cdata = cdata;
257 }
258
259 void wxSound::OnPlayBuffer(wxSndBuffer& buf)
260 {
261 m_lastbuf = &buf;
262 if (m_sndcbk)
263 m_sndcbk(*this, buf, m_cdata);
264 }