1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
7 // --------------------------------------------------------------------------
9 #pragma implementation "sndesd.cpp"
12 #include <sys/types.h>
16 #include <wx/string.h>
25 #define MY_ESD_NAME "wxWindows/wxSoundStreamESD"
27 // -----------------------------------------------------------------------------------------------
28 // wxSoundStreamESD: ESD sound driver
31 // --------------------------------------------------------------------------------------------
32 // Constructors/Destructors
33 // --------------------------------------------------------------------------------------------
35 wxSoundStreamESD::wxSoundStreamESD(const wxString
& hostname
)
37 wxSoundFormatPcm pcm_default
;
39 // First, we make some basic test: is there ESD on this computer ?
41 if (hostname
.IsNull())
42 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
43 hostname
.mb_str(), MY_ESD_NAME
);
45 m_fd_output
= esd_play_stream(ESD_PLAY
| ESD_STREAM
, 22050,
47 if (m_fd_output
== -1) {
48 // Answer: no. We return with an error.
49 m_snderror
= wxSOUND_INVDEV
;
53 // Close this unuseful stream.
54 esd_close(m_fd_output
);
56 m_hostname
= hostname
;
58 // Set the default audio format
59 SetSoundFormat(pcm_default
);
61 // Initialize some variable
62 m_snderror
= wxSOUND_NOERROR
;
68 wxSoundStreamESD::~wxSoundStreamESD()
70 // Close all remaining streams
72 esd_close(m_fd_output
);
74 esd_close(m_fd_input
);
77 // --------------------------------------------------------------------------------------------
78 // Read several samples
79 // --------------------------------------------------------------------------------------------
80 wxSoundStream
& wxSoundStreamESD::Read(void *buffer
, wxUint32 len
)
84 m_lastcount
= (wxUint32
)ret
= read(m_fd_input
, buffer
, len
);
87 m_snderror
= wxSOUND_IOERROR
;
89 m_snderror
= wxSOUND_NOERROR
;
94 // --------------------------------------------------------------------------------------------
95 // Write several samples
96 // --------------------------------------------------------------------------------------------
97 wxSoundStream
& wxSoundStreamESD::Write(const void *buffer
, wxUint32 len
)
101 m_lastcount
= (wxUint32
)ret
= write(m_fd_output
, buffer
, len
);
104 m_snderror
= wxSOUND_IOERROR
;
106 m_snderror
= wxSOUND_NOERROR
;
113 // --------------------------------------------------------------------------------------------
114 // SetSoundFormat(): this function specifies which format we want and which format is available
115 // --------------------------------------------------------------------------------------------
117 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase
& format
)
119 wxSoundFormatPcm
*pcm_format
;
121 if (format
.GetType() != wxSOUND_PCM
) {
122 m_snderror
= wxSOUND_INVFRMT
;
126 if (m_fd_input
== -1 && m_fd_output
== -1) {
127 m_snderror
= wxSOUND_INVDEV
;
134 m_sndformat
= format
.Clone();
136 m_snderror
= wxSOUND_MEMERROR
;
139 pcm_format
= (wxSoundFormatPcm
*)m_sndformat
;
141 // Detect the best format
142 DetectBest(pcm_format
);
144 m_snderror
= wxSOUND_NOERROR
;
145 if (*pcm_format
!= format
) {
146 m_snderror
= wxSOUND_NOEXACT
;
152 // --------------------------------------------------------------------------------------------
153 // _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is ready for a next
155 // --------------------------------------------------------------------------------------------
157 static void _wxSound_OSS_CBack(gpointer data
, int source
,
158 GdkInputCondition condition
)
160 wxSoundStreamESD
*esd
= (wxSoundStreamESD
*)data
;
164 esd
->WakeUpEvt(wxSOUND_INPUT
);
166 case GDK_INPUT_WRITE
:
167 esd
->WakeUpEvt(wxSOUND_OUTPUT
);
175 // --------------------------------------------------------------------------------------------
176 // WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the C++ protection
177 // --------------------------------------------------------------------------------------------
178 void wxSoundStreamESD::WakeUpEvt(int evt
)
184 // --------------------------------------------------------------------------------------------
185 // StartProduction(): see wxSoundStream
186 // --------------------------------------------------------------------------------------------
187 bool wxSoundStreamESD::StartProduction(int evt
)
189 wxSoundFormatPcm
*pcm
;
195 pcm
= (wxSoundFormatPcm
*)m_sndformat
;
197 flag
|= (pcm
->GetBPS() == 16) ? ESD_BITS16
: ESD_BITS8
;
198 flag
|= (pcm
->GetChannels() == 2) ? ESD_STEREO
: ESD_MONO
;
200 if ((evt
& wxSOUND_OUTPUT
) != 0) {
201 flag
|= ESD_PLAY
| ESD_STREAM
;
202 m_fd_output
= esd_play_stream(flag
, pcm
->GetSampleRate(), NULL
,
206 if ((evt
& wxSOUND_INPUT
) != 0) {
207 flag
|= ESD_RECORD
| ESD_STREAM
;
208 m_fd_input
= esd_record_stream(flag
, pcm
->GetSampleRate(), NULL
,
213 if ((evt
& wxSOUND_OUTPUT
) != 0) {
214 m_tag_output
= gdk_input_add(m_fd_output
, GDK_INPUT_WRITE
, _wxSound_OSS_CBack
, (gpointer
)this);
216 if ((evt
& wxSOUND_INPUT
) != 0) {
217 m_tag_input
= gdk_input_add(m_fd_input
, GDK_INPUT_READ
, _wxSound_OSS_CBack
, (gpointer
)this);
227 bool wxSoundStreamESD::StopProduction()
232 if (m_fd_input
!= -1) {
233 esd_close(m_fd_input
);
235 gdk_input_remove(m_tag_input
);
238 if (m_fd_output
!= -1) {
239 esd_close(m_fd_output
);
241 gdk_input_remove(m_tag_output
);
253 // Detect the closest format (The best).
255 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm
*pcm
)
257 wxSoundFormatPcm best_pcm
;
259 // We change neither the number of channels nor the sample rate because ESD is clever.
261 best_pcm
.SetSampleRate(pcm
->GetSampleRate());
262 best_pcm
.SetChannels(pcm
->GetChannels());
264 // It supports 16 bits
265 if (pcm
->GetBPS() == 16)
268 best_pcm
.SetOrder(wxLITTLE_ENDIAN
);
269 best_pcm
.Signed(TRUE
);
271 // Finally recopy the new format