1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
7 // --------------------------------------------------------------------------
9 #pragma implementation "sndesd.cpp"
12 #include "wx/wxprec.h"
16 #include "wx/string.h"
23 // --------------------------------------------------------------------------
25 // --------------------------------------------------------------------------
27 #include "wx/mmedia/sndbase.h"
28 #include "wx/mmedia/sndesd.h"
29 #include "wx/mmedia/sndpcm.h"
31 // --------------------------------------------------------------------------
33 // --------------------------------------------------------------------------
36 #include <sys/types.h>
45 // --------------------------------------------------------------------------
47 #define MY_ESD_NAME "wxWidgets/wxSoundStreamESD"
49 // --------------------------------------------------------------------------
50 // wxSoundStreamESD: ESD sound driver
52 // --------------------------------------------------------------------------
53 // Constructors/Destructors
54 // --------------------------------------------------------------------------
56 wxSoundStreamESD::wxSoundStreamESD(const wxString
& hostname
)
59 m_snderror
= wxSOUND_INVDEV
;
62 wxSoundFormatPcm pcm_default
;
64 // First, we make some basic test: is there ESD on this computer ?
67 if (hostname
.IsNull())
68 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
69 hostname
.mb_str(), MY_ESD_NAME
);
71 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
73 if (m_fd_output
== -1) {
74 // Answer: no. We return with an error.
75 m_snderror
= wxSOUND_INVDEV
;
79 // Close this unuseful stream.
80 esd_close(m_fd_output
);
82 m_hostname
= hostname
;
84 // Set the default audio format
85 SetSoundFormat(pcm_default
);
87 // Initialize some variable
88 m_snderror
= wxSOUND_NOERROR
;
94 #endif // defined HAVE_ESD_H
97 wxSoundStreamESD::~wxSoundStreamESD()
102 #endif // defined HAVE_ESD_H
105 // --------------------------------------------------------------------------
106 // Read several samples
107 // --------------------------------------------------------------------------
109 wxSoundStream
& wxSoundStreamESD::Read(void *buffer
, wxUint32 len
)
112 m_snderror
= wxSOUND_INVDEV
;
118 m_snderror
= wxSOUND_NOTSTARTED
;
122 ret
= read(m_fd_input
, buffer
, len
);
123 m_lastcount
= (wxUint32
)ret
;
126 m_snderror
= wxSOUND_IOERROR
;
128 m_snderror
= wxSOUND_NOERROR
;
131 #endif // defined HAVE_ESD_H
134 // --------------------------------------------------------------------------
135 // Write several samples
136 // --------------------------------------------------------------------------
137 wxSoundStream
& wxSoundStreamESD::Write(const void *buffer
, wxUint32 len
)
140 m_snderror
= wxSOUND_INVDEV
;
147 m_snderror
= wxSOUND_NOTSTARTED
;
151 ret
= write(m_fd_output
, buffer
, len
);
152 m_lastcount
= (wxUint32
)ret
;
155 m_snderror
= wxSOUND_IOERROR
;
157 m_snderror
= wxSOUND_NOERROR
;
162 #endif // defined HAVE_ESD_H
165 // --------------------------------------------------------------------------
166 // SetSoundFormat(): this function specifies which format we want and which
167 // format is available
168 // --------------------------------------------------------------------------
169 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase
& format
)
172 m_snderror
= wxSOUND_INVDEV
;
175 wxSoundFormatPcm
*pcm_format
;
177 if (format
.GetType() != wxSOUND_PCM
) {
178 m_snderror
= wxSOUND_INVFRMT
;
183 m_snderror
= wxSOUND_INVDEV
;
190 m_sndformat
= format
.Clone();
192 m_snderror
= wxSOUND_MEMERROR
;
195 pcm_format
= (wxSoundFormatPcm
*)m_sndformat
;
197 // Detect the best format
198 DetectBest(pcm_format
);
200 m_snderror
= wxSOUND_NOERROR
;
201 if (*pcm_format
!= format
) {
202 m_snderror
= wxSOUND_NOEXACT
;
206 #endif // defined HAVE_ESD_H
209 // --------------------------------------------------------------------------
210 // _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is
211 // ready for a next buffer.
212 // --------------------------------------------------------------------------
213 #if defined(__WXGTK__) && defined(HAVE_ESD_H)
214 static void _wxSound_OSS_CBack(gpointer data
, int source
,
215 GdkInputCondition condition
)
217 wxSoundStreamESD
*esd
= (wxSoundStreamESD
*)data
;
221 esd
->WakeUpEvt(wxSOUND_INPUT
);
223 case GDK_INPUT_WRITE
:
224 esd
->WakeUpEvt(wxSOUND_OUTPUT
);
233 // --------------------------------------------------------------------------
234 // WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the
236 // --------------------------------------------------------------------------
237 void wxSoundStreamESD::WakeUpEvt(int evt
)
243 // --------------------------------------------------------------------------
244 // StartProduction(): see wxSoundStream
245 // --------------------------------------------------------------------------
246 bool wxSoundStreamESD::StartProduction(int evt
)
249 m_snderror
= wxSOUND_INVDEV
;
252 wxSoundFormatPcm
*pcm
;
256 m_snderror
= wxSOUND_INVDEV
;
263 pcm
= (wxSoundFormatPcm
*)m_sndformat
;
265 flag
|= (pcm
->GetBPS() == 16) ? ESD_BITS16
: ESD_BITS8
;
266 flag
|= (pcm
->GetChannels() == 2) ? ESD_STEREO
: ESD_MONO
;
268 if ((evt
& wxSOUND_OUTPUT
) != 0) {
269 flag
|= ESD_PLAY
| ESD_STREAM
;
270 m_fd_output
= esd_play_stream(flag
, pcm
->GetSampleRate(), NULL
,
274 if ((evt
& wxSOUND_INPUT
) != 0) {
275 flag
|= ESD_RECORD
| ESD_STREAM
;
276 m_fd_input
= esd_record_stream(flag
, pcm
->GetSampleRate(), NULL
,
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);
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);
295 #endif // defined HAVE_ESD_H
298 // --------------------------------------------------------------------------
299 // StopProduction(): see wxSoundStream
300 // --------------------------------------------------------------------------
301 bool wxSoundStreamESD::StopProduction()
304 m_snderror
= wxSOUND_INVDEV
;
310 if (m_fd_input
!= -1) {
311 esd_close(m_fd_input
);
313 gdk_input_remove(m_tag_input
);
316 if (m_fd_output
!= -1) {
317 esd_close(m_fd_output
);
319 gdk_input_remove(m_tag_output
);
328 #endif // defined HAVE_ESD_H
332 // Detect the closest format (The best).
334 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm
*pcm
)
337 m_snderror
= wxSOUND_INVDEV
;
340 wxSoundFormatPcm best_pcm
;
342 // We change neither the number of channels nor the sample rate
343 // because ESD is clever.
345 best_pcm
.SetSampleRate(pcm
->GetSampleRate());
346 best_pcm
.SetChannels(pcm
->GetChannels());
348 // It supports 16 bits
349 if (pcm
->GetBPS() >= 16)
354 best_pcm
.SetOrder(wxLITTLE_ENDIAN
);
355 best_pcm
.Signed(true);
357 // Finally recopy the new format
359 #endif // defined HAVE_ESD_H