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