1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
8 // --------------------------------------------------------------------------
10 #pragma implementation "sndesd.cpp"
13 #include "wx/wxprec.h"
17 #include "wx/string.h"
24 // --------------------------------------------------------------------------
26 // --------------------------------------------------------------------------
28 #include "wx/mmedia/sndbase.h"
29 #include "wx/mmedia/sndesd.h"
30 #include "wx/mmedia/sndpcm.h"
32 // --------------------------------------------------------------------------
34 // --------------------------------------------------------------------------
37 #include <sys/types.h>
46 // --------------------------------------------------------------------------
48 #define MY_ESD_NAME "wxWidgets/wxSoundStreamESD"
50 // --------------------------------------------------------------------------
51 // wxSoundStreamESD: ESD sound driver
53 // --------------------------------------------------------------------------
54 // Constructors/Destructors
55 // --------------------------------------------------------------------------
57 wxSoundStreamESD::wxSoundStreamESD(const wxString
& hostname
)
60 m_snderror
= wxSOUND_INVDEV
;
63 wxSoundFormatPcm pcm_default
;
65 // First, we make some basic test: is there ESD on this computer ?
68 if (hostname
.IsNull())
69 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
70 hostname
.mb_str(), MY_ESD_NAME
);
72 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
74 if (m_fd_output
== -1) {
75 // Answer: no. We return with an error.
76 m_snderror
= wxSOUND_INVDEV
;
80 // Close this unuseful stream.
81 esd_close(m_fd_output
);
83 m_hostname
= hostname
;
85 // Set the default audio format
86 SetSoundFormat(pcm_default
);
88 // Initialize some variable
89 m_snderror
= wxSOUND_NOERROR
;
95 #endif // defined HAVE_ESD_H
98 wxSoundStreamESD::~wxSoundStreamESD()
103 #endif // defined HAVE_ESD_H
106 // --------------------------------------------------------------------------
107 // Read several samples
108 // --------------------------------------------------------------------------
110 wxSoundStream
& wxSoundStreamESD::Read(void *buffer
, wxUint32 len
)
113 m_snderror
= wxSOUND_INVDEV
;
119 m_snderror
= wxSOUND_NOTSTARTED
;
123 ret
= read(m_fd_input
, buffer
, len
);
124 m_lastcount
= (wxUint32
)ret
;
127 m_snderror
= wxSOUND_IOERROR
;
129 m_snderror
= wxSOUND_NOERROR
;
132 #endif // defined HAVE_ESD_H
135 // --------------------------------------------------------------------------
136 // Write several samples
137 // --------------------------------------------------------------------------
138 wxSoundStream
& wxSoundStreamESD::Write(const void *buffer
, wxUint32 len
)
141 m_snderror
= wxSOUND_INVDEV
;
148 m_snderror
= wxSOUND_NOTSTARTED
;
152 ret
= write(m_fd_output
, buffer
, len
);
153 m_lastcount
= (wxUint32
)ret
;
156 m_snderror
= wxSOUND_IOERROR
;
158 m_snderror
= wxSOUND_NOERROR
;
163 #endif // defined HAVE_ESD_H
166 // --------------------------------------------------------------------------
167 // SetSoundFormat(): this function specifies which format we want and which
168 // format is available
169 // --------------------------------------------------------------------------
170 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase
& format
)
173 m_snderror
= wxSOUND_INVDEV
;
176 wxSoundFormatPcm
*pcm_format
;
178 if (format
.GetType() != wxSOUND_PCM
) {
179 m_snderror
= wxSOUND_INVFRMT
;
184 m_snderror
= wxSOUND_INVDEV
;
191 m_sndformat
= format
.Clone();
193 m_snderror
= wxSOUND_MEMERROR
;
196 pcm_format
= (wxSoundFormatPcm
*)m_sndformat
;
198 // Detect the best format
199 DetectBest(pcm_format
);
201 m_snderror
= wxSOUND_NOERROR
;
202 if (*pcm_format
!= format
) {
203 m_snderror
= wxSOUND_NOEXACT
;
207 #endif // defined HAVE_ESD_H
210 // --------------------------------------------------------------------------
211 // _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is
212 // ready for a next buffer.
213 // --------------------------------------------------------------------------
214 #if defined(__WXGTK__) && defined(HAVE_ESD_H)
215 static void _wxSound_OSS_CBack(gpointer data
, int source
,
216 GdkInputCondition condition
)
218 wxSoundStreamESD
*esd
= (wxSoundStreamESD
*)data
;
222 esd
->WakeUpEvt(wxSOUND_INPUT
);
224 case GDK_INPUT_WRITE
:
225 esd
->WakeUpEvt(wxSOUND_OUTPUT
);
234 // --------------------------------------------------------------------------
235 // WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the
237 // --------------------------------------------------------------------------
238 void wxSoundStreamESD::WakeUpEvt(int evt
)
244 // --------------------------------------------------------------------------
245 // StartProduction(): see wxSoundStream
246 // --------------------------------------------------------------------------
247 bool wxSoundStreamESD::StartProduction(int evt
)
250 m_snderror
= wxSOUND_INVDEV
;
253 wxSoundFormatPcm
*pcm
;
257 m_snderror
= wxSOUND_INVDEV
;
264 pcm
= (wxSoundFormatPcm
*)m_sndformat
;
266 flag
|= (pcm
->GetBPS() == 16) ? ESD_BITS16
: ESD_BITS8
;
267 flag
|= (pcm
->GetChannels() == 2) ? ESD_STEREO
: ESD_MONO
;
269 if ((evt
& wxSOUND_OUTPUT
) != 0) {
270 flag
|= ESD_PLAY
| ESD_STREAM
;
271 m_fd_output
= esd_play_stream(flag
, pcm
->GetSampleRate(), NULL
,
275 if ((evt
& wxSOUND_INPUT
) != 0) {
276 flag
|= ESD_RECORD
| ESD_STREAM
;
277 m_fd_input
= esd_record_stream(flag
, pcm
->GetSampleRate(), NULL
,
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);
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);
296 #endif // defined HAVE_ESD_H
299 // --------------------------------------------------------------------------
300 // StopProduction(): see wxSoundStream
301 // --------------------------------------------------------------------------
302 bool wxSoundStreamESD::StopProduction()
305 m_snderror
= wxSOUND_INVDEV
;
311 if (m_fd_input
!= -1) {
312 esd_close(m_fd_input
);
314 gdk_input_remove(m_tag_input
);
317 if (m_fd_output
!= -1) {
318 esd_close(m_fd_output
);
320 gdk_input_remove(m_tag_output
);
329 #endif // defined HAVE_ESD_H
333 // Detect the closest format (The best).
335 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm
*pcm
)
338 m_snderror
= wxSOUND_INVDEV
;
341 wxSoundFormatPcm best_pcm
;
343 // We change neither the number of channels nor the sample rate
344 // because ESD is clever.
346 best_pcm
.SetSampleRate(pcm
->GetSampleRate());
347 best_pcm
.SetChannels(pcm
->GetChannels());
349 // It supports 16 bits
350 if (pcm
->GetBPS() >= 16)
355 best_pcm
.SetOrder(wxLITTLE_ENDIAN
);
356 best_pcm
.Signed(true);
358 // Finally recopy the new format
360 #endif // defined HAVE_ESD_H