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"
25 // --------------------------------------------------------------------------
27 // --------------------------------------------------------------------------
29 #include "wx/mmedia/sndbase.h"
30 #include "wx/mmedia/sndesd.h"
31 #include "wx/mmedia/sndpcm.h"
33 // --------------------------------------------------------------------------
35 // --------------------------------------------------------------------------
37 #include <sys/types.h>
45 // --------------------------------------------------------------------------
47 #define MY_ESD_NAME "wxWindows/wxSoundStreamESD"
49 // --------------------------------------------------------------------------
50 // wxSoundStreamESD: ESD sound driver
52 // --------------------------------------------------------------------------
53 // Constructors/Destructors
54 // --------------------------------------------------------------------------
56 wxSoundStreamESD::wxSoundStreamESD(const wxString
& hostname
)
58 wxSoundFormatPcm pcm_default
;
60 // First, we make some basic test: is there ESD on this computer ?
63 if (hostname
.IsNull())
64 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
65 hostname
.mb_str(), MY_ESD_NAME
);
67 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
69 if (m_fd_output
== -1) {
70 // Answer: no. We return with an error.
71 m_snderror
= wxSOUND_INVDEV
;
75 // Close this unuseful stream.
76 esd_close(m_fd_output
);
78 m_hostname
= hostname
;
80 // Set the default audio format
81 SetSoundFormat(pcm_default
);
83 // Initialize some variable
84 m_snderror
= wxSOUND_NOERROR
;
92 wxSoundStreamESD::~wxSoundStreamESD()
98 // --------------------------------------------------------------------------
99 // Read several samples
100 // --------------------------------------------------------------------------
102 wxSoundStream
& wxSoundStreamESD::Read(void *buffer
, wxUint32 len
)
107 m_snderror
= wxSOUND_NOTSTARTED
;
111 m_lastcount
= (wxUint32
)ret
= read(m_fd_input
, buffer
, len
);
114 m_snderror
= wxSOUND_IOERROR
;
116 m_snderror
= wxSOUND_NOERROR
;
121 // --------------------------------------------------------------------------
122 // Write several samples
123 // --------------------------------------------------------------------------
124 wxSoundStream
& wxSoundStreamESD::Write(const void *buffer
, wxUint32 len
)
130 m_snderror
= wxSOUND_NOTSTARTED
;
134 m_lastcount
= (wxUint32
)ret
= write(m_fd_output
, buffer
, len
);
137 m_snderror
= wxSOUND_IOERROR
;
139 m_snderror
= wxSOUND_NOERROR
;
146 // --------------------------------------------------------------------------
147 // SetSoundFormat(): this function specifies which format we want and which
148 // format is available
149 // --------------------------------------------------------------------------
150 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase
& format
)
152 wxSoundFormatPcm
*pcm_format
;
154 if (format
.GetType() != wxSOUND_PCM
) {
155 m_snderror
= wxSOUND_INVFRMT
;
160 m_snderror
= wxSOUND_INVDEV
;
167 m_sndformat
= format
.Clone();
169 m_snderror
= wxSOUND_MEMERROR
;
172 pcm_format
= (wxSoundFormatPcm
*)m_sndformat
;
174 // Detect the best format
175 DetectBest(pcm_format
);
177 m_snderror
= wxSOUND_NOERROR
;
178 if (*pcm_format
!= format
) {
179 m_snderror
= wxSOUND_NOEXACT
;
185 // --------------------------------------------------------------------------
186 // _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is
187 // ready for a next buffer.
188 // --------------------------------------------------------------------------
190 static void _wxSound_OSS_CBack(gpointer data
, int source
,
191 GdkInputCondition condition
)
193 wxSoundStreamESD
*esd
= (wxSoundStreamESD
*)data
;
197 esd
->WakeUpEvt(wxSOUND_INPUT
);
199 case GDK_INPUT_WRITE
:
200 esd
->WakeUpEvt(wxSOUND_OUTPUT
);
209 // --------------------------------------------------------------------------
210 // WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the
212 // --------------------------------------------------------------------------
213 void wxSoundStreamESD::WakeUpEvt(int evt
)
219 // --------------------------------------------------------------------------
220 // StartProduction(): see wxSoundStream
221 // --------------------------------------------------------------------------
222 bool wxSoundStreamESD::StartProduction(int evt
)
224 wxSoundFormatPcm
*pcm
;
228 m_snderror
= wxSOUND_INVDEV
;
235 pcm
= (wxSoundFormatPcm
*)m_sndformat
;
237 flag
|= (pcm
->GetBPS() == 16) ? ESD_BITS16
: ESD_BITS8
;
238 flag
|= (pcm
->GetChannels() == 2) ? ESD_STEREO
: ESD_MONO
;
240 if ((evt
& wxSOUND_OUTPUT
) != 0) {
241 flag
|= ESD_PLAY
| ESD_STREAM
;
242 m_fd_output
= esd_play_stream(flag
, pcm
->GetSampleRate(), NULL
,
246 if ((evt
& wxSOUND_INPUT
) != 0) {
247 flag
|= ESD_RECORD
| ESD_STREAM
;
248 m_fd_input
= esd_record_stream(flag
, pcm
->GetSampleRate(), NULL
,
253 if ((evt
& wxSOUND_OUTPUT
) != 0) {
254 m_tag_output
= gdk_input_add(m_fd_output
, GDK_INPUT_WRITE
,
255 _wxSound_OSS_CBack
, (gpointer
)this);
257 if ((evt
& wxSOUND_INPUT
) != 0) {
258 m_tag_input
= gdk_input_add(m_fd_input
, GDK_INPUT_READ
,
259 _wxSound_OSS_CBack
, (gpointer
)this);
269 // --------------------------------------------------------------------------
270 // StopProduction(): see wxSoundStream
271 // --------------------------------------------------------------------------
272 bool wxSoundStreamESD::StopProduction()
277 if (m_fd_input
!= -1) {
278 esd_close(m_fd_input
);
280 gdk_input_remove(m_tag_input
);
283 if (m_fd_output
!= -1) {
284 esd_close(m_fd_output
);
286 gdk_input_remove(m_tag_output
);
298 // Detect the closest format (The best).
300 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm
*pcm
)
302 wxSoundFormatPcm best_pcm
;
304 // We change neither the number of channels nor the sample rate
305 // because ESD is clever.
307 best_pcm
.SetSampleRate(pcm
->GetSampleRate());
308 best_pcm
.SetChannels(pcm
->GetChannels());
310 // It supports 16 bits
311 if (pcm
->GetBPS() >= 16)
316 best_pcm
.SetOrder(wxLITTLE_ENDIAN
);
317 best_pcm
.Signed(TRUE
);
319 // Finally recopy the new format