1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
8 // --------------------------------------------------------------------------
10 #include "wx/wxprec.h"
14 #include "wx/string.h"
21 // --------------------------------------------------------------------------
23 // --------------------------------------------------------------------------
25 #include "wx/mmedia/sndbase.h"
26 #include "wx/mmedia/sndesd.h"
27 #include "wx/mmedia/sndpcm.h"
29 // --------------------------------------------------------------------------
31 // --------------------------------------------------------------------------
34 #include <sys/types.h>
43 // --------------------------------------------------------------------------
45 #define MY_ESD_NAME "wxWidgets/wxSoundStreamESD"
47 // --------------------------------------------------------------------------
48 // wxSoundStreamESD: ESD sound driver
50 // --------------------------------------------------------------------------
51 // Constructors/Destructors
52 // --------------------------------------------------------------------------
54 wxSoundStreamESD::wxSoundStreamESD(const wxString
& hostname
)
57 m_snderror
= wxSOUND_INVDEV
;
60 wxSoundFormatPcm pcm_default
;
62 // First, we make some basic test: is there ESD on this computer ?
65 if (hostname
.IsNull())
66 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
67 hostname
.mb_str(), MY_ESD_NAME
);
69 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
71 if (m_fd_output
== -1) {
72 // Answer: no. We return with an error.
73 m_snderror
= wxSOUND_INVDEV
;
77 // Close this unuseful stream.
78 esd_close(m_fd_output
);
80 m_hostname
= hostname
;
82 // Set the default audio format
83 SetSoundFormat(pcm_default
);
85 // Initialize some variable
86 m_snderror
= wxSOUND_NOERROR
;
92 #endif // defined HAVE_ESD_H
95 wxSoundStreamESD::~wxSoundStreamESD()
100 #endif // defined HAVE_ESD_H
103 // --------------------------------------------------------------------------
104 // Read several samples
105 // --------------------------------------------------------------------------
107 wxSoundStream
& wxSoundStreamESD::Read(void *buffer
, wxUint32 len
)
110 m_snderror
= wxSOUND_INVDEV
;
116 m_snderror
= wxSOUND_NOTSTARTED
;
120 ret
= read(m_fd_input
, buffer
, len
);
121 m_lastcount
= (wxUint32
)ret
;
124 m_snderror
= wxSOUND_IOERROR
;
126 m_snderror
= wxSOUND_NOERROR
;
129 #endif // defined HAVE_ESD_H
132 // --------------------------------------------------------------------------
133 // Write several samples
134 // --------------------------------------------------------------------------
135 wxSoundStream
& wxSoundStreamESD::Write(const void *buffer
, wxUint32 len
)
138 m_snderror
= wxSOUND_INVDEV
;
145 m_snderror
= wxSOUND_NOTSTARTED
;
149 ret
= write(m_fd_output
, buffer
, len
);
150 m_lastcount
= (wxUint32
)ret
;
153 m_snderror
= wxSOUND_IOERROR
;
155 m_snderror
= wxSOUND_NOERROR
;
160 #endif // defined HAVE_ESD_H
163 // --------------------------------------------------------------------------
164 // SetSoundFormat(): this function specifies which format we want and which
165 // format is available
166 // --------------------------------------------------------------------------
167 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase
& format
)
170 m_snderror
= wxSOUND_INVDEV
;
173 wxSoundFormatPcm
*pcm_format
;
175 if (format
.GetType() != wxSOUND_PCM
) {
176 m_snderror
= wxSOUND_INVFRMT
;
181 m_snderror
= wxSOUND_INVDEV
;
188 m_sndformat
= format
.Clone();
190 m_snderror
= wxSOUND_MEMERROR
;
193 pcm_format
= (wxSoundFormatPcm
*)m_sndformat
;
195 // Detect the best format
196 DetectBest(pcm_format
);
198 m_snderror
= wxSOUND_NOERROR
;
199 if (*pcm_format
!= format
) {
200 m_snderror
= wxSOUND_NOEXACT
;
204 #endif // defined HAVE_ESD_H
207 // --------------------------------------------------------------------------
208 // _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is
209 // ready for a next buffer.
210 // --------------------------------------------------------------------------
211 #if defined(__WXGTK__) && defined(HAVE_ESD_H)
212 static void _wxSound_OSS_CBack(gpointer data
, int source
,
213 GdkInputCondition condition
)
215 wxSoundStreamESD
*esd
= (wxSoundStreamESD
*)data
;
219 esd
->WakeUpEvt(wxSOUND_INPUT
);
221 case GDK_INPUT_WRITE
:
222 esd
->WakeUpEvt(wxSOUND_OUTPUT
);
231 // --------------------------------------------------------------------------
232 // WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the
234 // --------------------------------------------------------------------------
235 void wxSoundStreamESD::WakeUpEvt(int evt
)
241 // --------------------------------------------------------------------------
242 // StartProduction(): see wxSoundStream
243 // --------------------------------------------------------------------------
244 bool wxSoundStreamESD::StartProduction(int evt
)
247 m_snderror
= wxSOUND_INVDEV
;
250 wxSoundFormatPcm
*pcm
;
254 m_snderror
= wxSOUND_INVDEV
;
261 pcm
= (wxSoundFormatPcm
*)m_sndformat
;
263 flag
|= (pcm
->GetBPS() == 16) ? ESD_BITS16
: ESD_BITS8
;
264 flag
|= (pcm
->GetChannels() == 2) ? ESD_STEREO
: ESD_MONO
;
266 if ((evt
& wxSOUND_OUTPUT
) != 0) {
267 flag
|= ESD_PLAY
| ESD_STREAM
;
268 m_fd_output
= esd_play_stream(flag
, pcm
->GetSampleRate(), NULL
,
272 if ((evt
& wxSOUND_INPUT
) != 0) {
273 flag
|= ESD_RECORD
| ESD_STREAM
;
274 m_fd_input
= esd_record_stream(flag
, pcm
->GetSampleRate(), NULL
,
279 if ((evt
& wxSOUND_OUTPUT
) != 0) {
280 m_tag_output
= gdk_input_add(m_fd_output
, GDK_INPUT_WRITE
,
281 _wxSound_OSS_CBack
, (gpointer
)this);
283 if ((evt
& wxSOUND_INPUT
) != 0) {
284 m_tag_input
= gdk_input_add(m_fd_input
, GDK_INPUT_READ
,
285 _wxSound_OSS_CBack
, (gpointer
)this);
293 #endif // defined HAVE_ESD_H
296 // --------------------------------------------------------------------------
297 // StopProduction(): see wxSoundStream
298 // --------------------------------------------------------------------------
299 bool wxSoundStreamESD::StopProduction()
302 m_snderror
= wxSOUND_INVDEV
;
308 if (m_fd_input
!= -1) {
309 esd_close(m_fd_input
);
311 gdk_input_remove(m_tag_input
);
314 if (m_fd_output
!= -1) {
315 esd_close(m_fd_output
);
317 gdk_input_remove(m_tag_output
);
326 #endif // defined HAVE_ESD_H
330 // Detect the closest format (The best).
332 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm
*pcm
)
335 m_snderror
= wxSOUND_INVDEV
;
338 wxSoundFormatPcm best_pcm
;
340 // We change neither the number of channels nor the sample rate
341 // because ESD is clever.
343 best_pcm
.SetSampleRate(pcm
->GetSampleRate());
344 best_pcm
.SetChannels(pcm
->GetChannels());
346 // It supports 16 bits
347 if (pcm
->GetBPS() >= 16)
352 best_pcm
.SetOrder(wxLITTLE_ENDIAN
);
353 best_pcm
.Signed(true);
355 // Finally recopy the new format
357 #endif // defined HAVE_ESD_H