]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/mmedia/sndesd.cpp
corrected version number extraction
[wxWidgets.git] / contrib / src / mmedia / sndesd.cpp
CommitLineData
e8482f24
GL
1// --------------------------------------------------------------------------
2// Name: sndesd.cpp
3// Purpose:
4// Date: 08/11/1999
5// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
6// CVSID: $Id$
58b9c9ba 7// wxWindows licence
e8482f24
GL
8// --------------------------------------------------------------------------
9#ifdef __GNUG__
10#pragma implementation "sndesd.cpp"
11#endif
12
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include "wx/defs.h"
17 #include "wx/string.h"
18#endif
19
20#ifdef __BORLANDC__
21 #pragma hdrstop
22#endif
23
24// --------------------------------------------------------------------------
25// MMedia headers
26// --------------------------------------------------------------------------
27
28#include "wx/mmedia/sndbase.h"
29#include "wx/mmedia/sndesd.h"
30#include "wx/mmedia/sndpcm.h"
31
32// --------------------------------------------------------------------------
33// System headers
34// --------------------------------------------------------------------------
35
a7b1654d 36#ifdef HAVE_ESD_H
e8482f24
GL
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <unistd.h>
40#include <esd.h>
41#ifdef __WXGTK__
42#include <gdk/gdk.h>
43#endif
a7b1654d 44#endif
e8482f24
GL
45
46// --------------------------------------------------------------------------
47
be5a51fb 48#define MY_ESD_NAME "wxWidgets/wxSoundStreamESD"
e8482f24
GL
49
50// --------------------------------------------------------------------------
51// wxSoundStreamESD: ESD sound driver
52
53// --------------------------------------------------------------------------
54// Constructors/Destructors
55// --------------------------------------------------------------------------
56
57wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
58{
a7b1654d
MB
59#ifndef HAVE_ESD_H
60 m_snderror = wxSOUND_INVDEV;
61 return;
62#else
e8482f24 63 wxSoundFormatPcm pcm_default;
b7ecdec5 64
e8482f24 65 // First, we make some basic test: is there ESD on this computer ?
dea7e44a 66 m_esd_ok = false;
b7ecdec5 67
e8482f24 68 if (hostname.IsNull())
b7ecdec5 69 m_fd_output = esd_play_stream(ESD_PLAY | ESD_STREAM, 22050,
e8482f24
GL
70 hostname.mb_str(), MY_ESD_NAME);
71 else
b7ecdec5 72 m_fd_output = esd_play_stream(ESD_PLAY | ESD_STREAM, 22050,
e8482f24
GL
73 NULL, MY_ESD_NAME);
74 if (m_fd_output == -1) {
75 // Answer: no. We return with an error.
76 m_snderror = wxSOUND_INVDEV;
77 return;
78 }
b7ecdec5 79
e8482f24
GL
80 // Close this unuseful stream.
81 esd_close(m_fd_output);
b7ecdec5 82
e8482f24 83 m_hostname = hostname;
b7ecdec5 84
e8482f24
GL
85 // Set the default audio format
86 SetSoundFormat(pcm_default);
b7ecdec5 87
e8482f24
GL
88 // Initialize some variable
89 m_snderror = wxSOUND_NOERROR;
dea7e44a
WS
90 m_esd_stop = true;
91 m_q_filled = true;
92 m_esd_ok = true;
e8482f24
GL
93 m_fd_output= -1;
94 m_fd_input = -1;
a7b1654d 95#endif // defined HAVE_ESD_H
e8482f24
GL
96}
97
98wxSoundStreamESD::~wxSoundStreamESD()
99{
a7b1654d 100#ifdef HAVE_ESD_H
e8482f24
GL
101 if (!m_esd_stop)
102 StopProduction();
a7b1654d 103#endif // defined HAVE_ESD_H
e8482f24
GL
104}
105
106// --------------------------------------------------------------------------
107// Read several samples
108// --------------------------------------------------------------------------
109
110wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len)
111{
a7b1654d
MB
112#ifndef HAVE_ESD_H
113 m_snderror = wxSOUND_INVDEV;
114 return *this;
115#else
e8482f24 116 int ret;
b7ecdec5 117
e8482f24
GL
118 if (m_esd_stop) {
119 m_snderror = wxSOUND_NOTSTARTED;
120 return *this;
121 }
b7ecdec5
WS
122
123 ret = read(m_fd_input, buffer, len);
124 m_lastcount = (wxUint32)ret;
125
e8482f24
GL
126 if (ret < 0)
127 m_snderror = wxSOUND_IOERROR;
128 else
129 m_snderror = wxSOUND_NOERROR;
b7ecdec5 130
e8482f24 131 return *this;
a7b1654d 132#endif // defined HAVE_ESD_H
e8482f24
GL
133}
134
135// --------------------------------------------------------------------------
136// Write several samples
137// --------------------------------------------------------------------------
138wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
139{
a7b1654d
MB
140#ifndef HAVE_ESD_H
141 m_snderror = wxSOUND_INVDEV;
142 return *this;
143#else
e8482f24
GL
144 int ret;
145
146 if (m_esd_stop) {
147 m_lastcount = 0;
148 m_snderror = wxSOUND_NOTSTARTED;
149 return *this;
150 }
b7ecdec5
WS
151
152 ret = write(m_fd_output, buffer, len);
153 m_lastcount = (wxUint32)ret;
154
e8482f24
GL
155 if (ret < 0)
156 m_snderror = wxSOUND_IOERROR;
157 else
158 m_snderror = wxSOUND_NOERROR;
b7ecdec5 159
dea7e44a 160 m_q_filled = true;
b7ecdec5 161
e8482f24 162 return *this;
a7b1654d 163#endif // defined HAVE_ESD_H
e8482f24
GL
164}
165
166// --------------------------------------------------------------------------
167// SetSoundFormat(): this function specifies which format we want and which
168// format is available
169// --------------------------------------------------------------------------
170bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
171{
a7b1654d
MB
172#ifndef HAVE_ESD_H
173 m_snderror = wxSOUND_INVDEV;
dea7e44a 174 return false;
a7b1654d 175#else
e8482f24 176 wxSoundFormatPcm *pcm_format;
b7ecdec5 177
e8482f24
GL
178 if (format.GetType() != wxSOUND_PCM) {
179 m_snderror = wxSOUND_INVFRMT;
dea7e44a 180 return false;
e8482f24
GL
181 }
182
183 if (!m_esd_ok) {
184 m_snderror = wxSOUND_INVDEV;
dea7e44a 185 return false;
e8482f24 186 }
b7ecdec5 187
e8482f24
GL
188 if (m_sndformat)
189 delete m_sndformat;
b7ecdec5 190
e8482f24
GL
191 m_sndformat = format.Clone();
192 if (!m_sndformat) {
193 m_snderror = wxSOUND_MEMERROR;
dea7e44a 194 return false;
e8482f24
GL
195 }
196 pcm_format = (wxSoundFormatPcm *)m_sndformat;
b7ecdec5 197
e8482f24
GL
198 // Detect the best format
199 DetectBest(pcm_format);
b7ecdec5 200
e8482f24
GL
201 m_snderror = wxSOUND_NOERROR;
202 if (*pcm_format != format) {
203 m_snderror = wxSOUND_NOEXACT;
dea7e44a 204 return false;
e8482f24 205 }
dea7e44a 206 return true;
a7b1654d 207#endif // defined HAVE_ESD_H
e8482f24
GL
208}
209
210// --------------------------------------------------------------------------
211// _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is
212// ready for a next buffer.
213// --------------------------------------------------------------------------
a7b1654d 214#if defined(__WXGTK__) && defined(HAVE_ESD_H)
e8482f24
GL
215static void _wxSound_OSS_CBack(gpointer data, int source,
216 GdkInputCondition condition)
217{
218 wxSoundStreamESD *esd = (wxSoundStreamESD *)data;
b7ecdec5 219
e8482f24
GL
220 switch (condition) {
221 case GDK_INPUT_READ:
222 esd->WakeUpEvt(wxSOUND_INPUT);
223 break;
224 case GDK_INPUT_WRITE:
225 esd->WakeUpEvt(wxSOUND_OUTPUT);
226 break;
227 default:
228 break;
229 }
230}
231#endif
232
233
234// --------------------------------------------------------------------------
235// WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the
236// C++ protection
237// --------------------------------------------------------------------------
238void wxSoundStreamESD::WakeUpEvt(int evt)
239{
dea7e44a 240 m_q_filled = false;
e8482f24
GL
241 OnSoundEvent(evt);
242}
243
244// --------------------------------------------------------------------------
245// StartProduction(): see wxSoundStream
246// --------------------------------------------------------------------------
247bool wxSoundStreamESD::StartProduction(int evt)
248{
a7b1654d
MB
249#ifndef HAVE_ESD_H
250 m_snderror = wxSOUND_INVDEV;
dea7e44a 251 return false;
a7b1654d 252#else
e8482f24
GL
253 wxSoundFormatPcm *pcm;
254 int flag = 0;
255
256 if (!m_esd_ok) {
257 m_snderror = wxSOUND_INVDEV;
dea7e44a 258 return false;
e8482f24 259 }
b7ecdec5 260
e8482f24
GL
261 if (!m_esd_stop)
262 StopProduction();
b7ecdec5 263
e8482f24 264 pcm = (wxSoundFormatPcm *)m_sndformat;
b7ecdec5 265
e8482f24
GL
266 flag |= (pcm->GetBPS() == 16) ? ESD_BITS16 : ESD_BITS8;
267 flag |= (pcm->GetChannels() == 2) ? ESD_STEREO : ESD_MONO;
b7ecdec5 268
e8482f24
GL
269 if ((evt & wxSOUND_OUTPUT) != 0) {
270 flag |= ESD_PLAY | ESD_STREAM;
271 m_fd_output = esd_play_stream(flag, pcm->GetSampleRate(), NULL,
272 MY_ESD_NAME);
b7ecdec5
WS
273 }
274
e8482f24
GL
275 if ((evt & wxSOUND_INPUT) != 0) {
276 flag |= ESD_RECORD | ESD_STREAM;
277 m_fd_input = esd_record_stream(flag, pcm->GetSampleRate(), NULL,
278 MY_ESD_NAME);
279 }
b7ecdec5 280
e8482f24
GL
281#ifdef __WXGTK__
282 if ((evt & wxSOUND_OUTPUT) != 0) {
283 m_tag_output = gdk_input_add(m_fd_output, GDK_INPUT_WRITE,
284 _wxSound_OSS_CBack, (gpointer)this);
285 }
286 if ((evt & wxSOUND_INPUT) != 0) {
287 m_tag_input = gdk_input_add(m_fd_input, GDK_INPUT_READ,
288 _wxSound_OSS_CBack, (gpointer)this);
289 }
290#endif
b7ecdec5 291
dea7e44a
WS
292 m_esd_stop = false;
293 m_q_filled = false;
b7ecdec5 294
dea7e44a 295 return true;
a7b1654d 296#endif // defined HAVE_ESD_H
e8482f24
GL
297}
298
299// --------------------------------------------------------------------------
300// StopProduction(): see wxSoundStream
301// --------------------------------------------------------------------------
302bool wxSoundStreamESD::StopProduction()
303{
a7b1654d
MB
304#ifndef HAVE_ESD_H
305 m_snderror = wxSOUND_INVDEV;
dea7e44a 306 return false;
a7b1654d 307#else
e8482f24 308 if (m_esd_stop)
dea7e44a 309 return false;
b7ecdec5 310
e8482f24
GL
311 if (m_fd_input != -1) {
312 esd_close(m_fd_input);
313#ifdef __WXGTK__
314 gdk_input_remove(m_tag_input);
315#endif
316 }
317 if (m_fd_output != -1) {
318 esd_close(m_fd_output);
319#ifdef __WXGTK__
320 gdk_input_remove(m_tag_output);
321#endif
322 }
b7ecdec5 323
e8482f24
GL
324 m_fd_input = -1;
325 m_fd_output= -1;
dea7e44a
WS
326 m_esd_stop = true;
327 m_q_filled = true;
328 return true;
a7b1654d 329#endif // defined HAVE_ESD_H
e8482f24
GL
330}
331
332//
333// Detect the closest format (The best).
334//
335void wxSoundStreamESD::DetectBest(wxSoundFormatPcm *pcm)
336{
a7b1654d
MB
337#ifndef HAVE_ESD_H
338 m_snderror = wxSOUND_INVDEV;
339 return;
340#else
e8482f24
GL
341 wxSoundFormatPcm best_pcm;
342
343 // We change neither the number of channels nor the sample rate
344 // because ESD is clever.
b7ecdec5 345
e8482f24
GL
346 best_pcm.SetSampleRate(pcm->GetSampleRate());
347 best_pcm.SetChannels(pcm->GetChannels());
b7ecdec5 348
e8482f24
GL
349 // It supports 16 bits
350 if (pcm->GetBPS() >= 16)
351 best_pcm.SetBPS(16);
352 else
353 best_pcm.SetBPS(8);
354
355 best_pcm.SetOrder(wxLITTLE_ENDIAN);
dea7e44a 356 best_pcm.Signed(true);
b7ecdec5 357
e8482f24
GL
358 // Finally recopy the new format
359 *pcm = best_pcm;
a7b1654d 360#endif // defined HAVE_ESD_H
e8482f24 361}
15e8daec 362