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 // --------------------------------------------------------------------------
35 #include <sys/types.h>
43 // --------------------------------------------------------------------------
45 #define MY_ESD_NAME "wxWindows/wxSoundStreamESD"
47 // --------------------------------------------------------------------------
48 // wxSoundStreamESD: ESD sound driver
50 // --------------------------------------------------------------------------
51 // Constructors/Destructors
52 // --------------------------------------------------------------------------
54 wxSoundStreamESD::wxSoundStreamESD(const wxString
& hostname
)
56 wxSoundFormatPcm pcm_default
;
58 // First, we make some basic test: is there ESD on this computer ?
61 if (hostname
.IsNull())
62 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
63 hostname
.mb_str(), MY_ESD_NAME
);
65 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
67 if (m_fd_output
== -1) {
68 // Answer: no. We return with an error.
69 m_snderror
= wxSOUND_INVDEV
;
73 // Close this unuseful stream.
74 esd_close(m_fd_output
);
76 m_hostname
= hostname
;
78 // Set the default audio format
79 SetSoundFormat(pcm_default
);
81 // Initialize some variable
82 m_snderror
= wxSOUND_NOERROR
;
90 wxSoundStreamESD::~wxSoundStreamESD()
96 // --------------------------------------------------------------------------
97 // Read several samples
98 // --------------------------------------------------------------------------
100 wxSoundStream
& wxSoundStreamESD::Read(void *buffer
, wxUint32 len
)
105 m_snderror
= wxSOUND_NOTSTARTED
;
109 m_lastcount
= (wxUint32
)ret
= read(m_fd_input
, buffer
, len
);
112 m_snderror
= wxSOUND_IOERROR
;
114 m_snderror
= wxSOUND_NOERROR
;
119 // --------------------------------------------------------------------------
120 // Write several samples
121 // --------------------------------------------------------------------------
122 wxSoundStream
& wxSoundStreamESD::Write(const void *buffer
, wxUint32 len
)
128 m_snderror
= wxSOUND_NOTSTARTED
;
132 m_lastcount
= (wxUint32
)ret
= write(m_fd_output
, buffer
, len
);
135 m_snderror
= wxSOUND_IOERROR
;
137 m_snderror
= wxSOUND_NOERROR
;
144 // --------------------------------------------------------------------------
145 // SetSoundFormat(): this function specifies which format we want and which
146 // format is available
147 // --------------------------------------------------------------------------
148 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase
& format
)
150 wxSoundFormatPcm
*pcm_format
;
152 if (format
.GetType() != wxSOUND_PCM
) {
153 m_snderror
= wxSOUND_INVFRMT
;
158 m_snderror
= wxSOUND_INVDEV
;
165 m_sndformat
= format
.Clone();
167 m_snderror
= wxSOUND_MEMERROR
;
170 pcm_format
= (wxSoundFormatPcm
*)m_sndformat
;
172 // Detect the best format
173 DetectBest(pcm_format
);
175 m_snderror
= wxSOUND_NOERROR
;
176 if (*pcm_format
!= format
) {
177 m_snderror
= wxSOUND_NOEXACT
;
183 // --------------------------------------------------------------------------
184 // _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is
185 // ready for a next buffer.
186 // --------------------------------------------------------------------------
188 static void _wxSound_OSS_CBack(gpointer data
, int source
,
189 GdkInputCondition condition
)
191 wxSoundStreamESD
*esd
= (wxSoundStreamESD
*)data
;
195 esd
->WakeUpEvt(wxSOUND_INPUT
);
197 case GDK_INPUT_WRITE
:
198 esd
->WakeUpEvt(wxSOUND_OUTPUT
);
207 // --------------------------------------------------------------------------
208 // WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the
210 // --------------------------------------------------------------------------
211 void wxSoundStreamESD::WakeUpEvt(int evt
)
217 // --------------------------------------------------------------------------
218 // StartProduction(): see wxSoundStream
219 // --------------------------------------------------------------------------
220 bool wxSoundStreamESD::StartProduction(int evt
)
222 wxSoundFormatPcm
*pcm
;
226 m_snderror
= wxSOUND_INVDEV
;
233 pcm
= (wxSoundFormatPcm
*)m_sndformat
;
235 flag
|= (pcm
->GetBPS() == 16) ? ESD_BITS16
: ESD_BITS8
;
236 flag
|= (pcm
->GetChannels() == 2) ? ESD_STEREO
: ESD_MONO
;
238 if ((evt
& wxSOUND_OUTPUT
) != 0) {
239 flag
|= ESD_PLAY
| ESD_STREAM
;
240 m_fd_output
= esd_play_stream(flag
, pcm
->GetSampleRate(), NULL
,
244 if ((evt
& wxSOUND_INPUT
) != 0) {
245 flag
|= ESD_RECORD
| ESD_STREAM
;
246 m_fd_input
= esd_record_stream(flag
, pcm
->GetSampleRate(), NULL
,
251 if ((evt
& wxSOUND_OUTPUT
) != 0) {
252 m_tag_output
= gdk_input_add(m_fd_output
, GDK_INPUT_WRITE
,
253 _wxSound_OSS_CBack
, (gpointer
)this);
255 if ((evt
& wxSOUND_INPUT
) != 0) {
256 m_tag_input
= gdk_input_add(m_fd_input
, GDK_INPUT_READ
,
257 _wxSound_OSS_CBack
, (gpointer
)this);
267 // --------------------------------------------------------------------------
268 // StopProduction(): see wxSoundStream
269 // --------------------------------------------------------------------------
270 bool wxSoundStreamESD::StopProduction()
275 if (m_fd_input
!= -1) {
276 esd_close(m_fd_input
);
278 gdk_input_remove(m_tag_input
);
281 if (m_fd_output
!= -1) {
282 esd_close(m_fd_output
);
284 gdk_input_remove(m_tag_output
);
296 // Detect the closest format (The best).
298 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm
*pcm
)
300 wxSoundFormatPcm best_pcm
;
302 // We change neither the number of channels nor the sample rate
303 // because ESD is clever.
305 best_pcm
.SetSampleRate(pcm
->GetSampleRate());
306 best_pcm
.SetChannels(pcm
->GetChannels());
308 // It supports 16 bits
309 if (pcm
->GetBPS() >= 16)
314 best_pcm
.SetOrder(wxLITTLE_ENDIAN
);
315 best_pcm
.Signed(TRUE
);
317 // Finally recopy the new format