]> git.saurik.com Git - wxWidgets.git/blame - utils/wxMMedia/sndsnd.cpp
* Fixes.
[wxWidgets.git] / utils / wxMMedia / sndsnd.cpp
CommitLineData
4d6306eb
GL
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
33wxSndBuffer::wxSndBuffer()
34 : m_sndmode(wxSND_OUTPUT), m_sndflags(0), m_sndoutput(NULL), m_sndcodec(NULL)
35{
36}
37
38wxSndBuffer::~wxSndBuffer()
39{
40}
41
42void 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
50void 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
60wxSndError wxSndBuffer::GetError()
61{
62 if (IsNotSet(wxSND_BUFERR))
63 return wxSND_NOERROR;
64 Clear(wxSND_BUFERR);
65 return m_snderror;
66}
67
68void wxSndBuffer::OnPlayFinished()
69{
70}
71
72void wxSndBuffer::OnBufferOutFinished()
73{
74}
75
76void wxSndBuffer::OnBufferInFinished(char *WXUNUSED(iobuf),
77 wxUint32& WXUNUSED(size))
78{
79}
80
81bool 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
92void wxSndBuffer::HardLock()
93{
94 m_mutex.Lock();
95}
96
97void wxSndBuffer::HardUnlock()
98{
99 m_mutex.Unlock();
100}
101
102void 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
116wxSndSimpleBuffer::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
127wxSndSimpleBuffer::~wxSndSimpleBuffer()
128{
129}
130
131void 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
149void wxSndSimpleBuffer::OnBufferOutFinished()
150{
151 if (m_sndptr >= m_sndsize)
152 OnPlayFinished();
153}
154
155void 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
172void wxSndSimpleBuffer::SetData(char *buffer, wxUint32 bufsize,
173 wxSndMode mode)
174{
175 m_sndbuf = buffer;
176 m_sndsize = bufsize;
177 m_sndmode = mode;
178}
179
180bool wxSndSimpleBuffer::RestartBuffer(wxSndMode mode)
181{
182 m_sndptr = 0;
183 return TRUE;
184}
185
186wxUint32 wxSndSimpleBuffer::GetSize() const
187{
188 return m_sndsize;
189}
190
191wxUint32 wxSndSimpleBuffer::Available() const
192{
193 return m_sndsize - m_sndptr;
194}
195
196// ----------------------------------------------------------------------------
197// wxSound: base sound driver implementation
198// ----------------------------------------------------------------------------
199
200wxSound::wxSound()
201 : wxObject(),
202 m_lastbuf(NULL), m_sndcbk(NULL), m_snderror(wxSND_NOERROR)
203{
204 m_buffers.Clear();
205}
206
207wxSound::~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
218bool 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
230bool 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
249void wxSound::Callback(wxSndCallback cbk)
250{
251 m_sndcbk = cbk;
252}
253
254void wxSound::SetClientData(char *cdata)
255{
256 m_cdata = cdata;
257}
258
259void wxSound::OnPlayBuffer(wxSndBuffer& buf)
260{
261 m_lastbuf = &buf;
262 if (m_sndcbk)
263 m_sndcbk(*this, buf, m_cdata);
264}