]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/mmedia/sndesd.cpp
implemented IsModified() and DiscardEdits()
[wxWidgets.git] / contrib / src / mmedia / sndesd.cpp
1 // --------------------------------------------------------------------------
2 // Name: sndesd.cpp
3 // Purpose:
4 // Date: 08/11/1999
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
6 // CVSID: $Id$
7 // --------------------------------------------------------------------------
8 #ifdef __GNUG__
9 #pragma implementation "sndesd.cpp"
10 #endif
11
12 #include "wx/wxprec.h"
13
14 #ifndef WX_PRECOMP
15 #include "wx/defs.h"
16 #include "wx/string.h"
17 #endif
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifdef HAVE_ESD_H
24
25 // --------------------------------------------------------------------------
26 // MMedia headers
27 // --------------------------------------------------------------------------
28
29 #include "wx/mmedia/sndbase.h"
30 #include "wx/mmedia/sndesd.h"
31 #include "wx/mmedia/sndpcm.h"
32
33 // --------------------------------------------------------------------------
34 // System headers
35 // --------------------------------------------------------------------------
36
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <unistd.h>
40 #include <esd.h>
41 #ifdef __WXGTK__
42 #include <gdk/gdk.h>
43 #endif
44
45 // --------------------------------------------------------------------------
46
47 #define MY_ESD_NAME "wxWindows/wxSoundStreamESD"
48
49 // --------------------------------------------------------------------------
50 // wxSoundStreamESD: ESD sound driver
51
52 // --------------------------------------------------------------------------
53 // Constructors/Destructors
54 // --------------------------------------------------------------------------
55
56 wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
57 {
58 wxSoundFormatPcm pcm_default;
59
60 // First, we make some basic test: is there ESD on this computer ?
61 m_esd_ok = FALSE;
62
63 if (hostname.IsNull())
64 m_fd_output = esd_play_stream(ESD_PLAY | ESD_STREAM, 22050,
65 hostname.mb_str(), MY_ESD_NAME);
66 else
67 m_fd_output = esd_play_stream(ESD_PLAY | ESD_STREAM, 22050,
68 NULL, MY_ESD_NAME);
69 if (m_fd_output == -1) {
70 // Answer: no. We return with an error.
71 m_snderror = wxSOUND_INVDEV;
72 return;
73 }
74
75 // Close this unuseful stream.
76 esd_close(m_fd_output);
77
78 m_hostname = hostname;
79
80 // Set the default audio format
81 SetSoundFormat(pcm_default);
82
83 // Initialize some variable
84 m_snderror = wxSOUND_NOERROR;
85 m_esd_stop = TRUE;
86 m_q_filled = TRUE;
87 m_esd_ok = TRUE;
88 m_fd_output= -1;
89 m_fd_input = -1;
90 }
91
92 wxSoundStreamESD::~wxSoundStreamESD()
93 {
94 if (!m_esd_stop)
95 StopProduction();
96 }
97
98 // --------------------------------------------------------------------------
99 // Read several samples
100 // --------------------------------------------------------------------------
101
102 wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len)
103 {
104 int ret;
105
106 if (m_esd_stop) {
107 m_snderror = wxSOUND_NOTSTARTED;
108 return *this;
109 }
110
111 m_lastcount = (wxUint32)ret = read(m_fd_input, buffer, len);
112
113 if (ret < 0)
114 m_snderror = wxSOUND_IOERROR;
115 else
116 m_snderror = wxSOUND_NOERROR;
117
118 return *this;
119 }
120
121 // --------------------------------------------------------------------------
122 // Write several samples
123 // --------------------------------------------------------------------------
124 wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
125 {
126 int ret;
127
128 if (m_esd_stop) {
129 m_lastcount = 0;
130 m_snderror = wxSOUND_NOTSTARTED;
131 return *this;
132 }
133
134 m_lastcount = (wxUint32)ret = write(m_fd_output, buffer, len);
135
136 if (ret < 0)
137 m_snderror = wxSOUND_IOERROR;
138 else
139 m_snderror = wxSOUND_NOERROR;
140
141 m_q_filled = TRUE;
142
143 return *this;
144 }
145
146 // --------------------------------------------------------------------------
147 // SetSoundFormat(): this function specifies which format we want and which
148 // format is available
149 // --------------------------------------------------------------------------
150 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
151 {
152 wxSoundFormatPcm *pcm_format;
153
154 if (format.GetType() != wxSOUND_PCM) {
155 m_snderror = wxSOUND_INVFRMT;
156 return FALSE;
157 }
158
159 if (!m_esd_ok) {
160 m_snderror = wxSOUND_INVDEV;
161 return FALSE;
162 }
163
164 if (m_sndformat)
165 delete m_sndformat;
166
167 m_sndformat = format.Clone();
168 if (!m_sndformat) {
169 m_snderror = wxSOUND_MEMERROR;
170 return FALSE;
171 }
172 pcm_format = (wxSoundFormatPcm *)m_sndformat;
173
174 // Detect the best format
175 DetectBest(pcm_format);
176
177 m_snderror = wxSOUND_NOERROR;
178 if (*pcm_format != format) {
179 m_snderror = wxSOUND_NOEXACT;
180 return FALSE;
181 }
182 return TRUE;
183 }
184
185 // --------------------------------------------------------------------------
186 // _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is
187 // ready for a next buffer.
188 // --------------------------------------------------------------------------
189 #ifdef __WXGTK__
190 static void _wxSound_OSS_CBack(gpointer data, int source,
191 GdkInputCondition condition)
192 {
193 wxSoundStreamESD *esd = (wxSoundStreamESD *)data;
194
195 switch (condition) {
196 case GDK_INPUT_READ:
197 esd->WakeUpEvt(wxSOUND_INPUT);
198 break;
199 case GDK_INPUT_WRITE:
200 esd->WakeUpEvt(wxSOUND_OUTPUT);
201 break;
202 default:
203 break;
204 }
205 }
206 #endif
207
208
209 // --------------------------------------------------------------------------
210 // WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the
211 // C++ protection
212 // --------------------------------------------------------------------------
213 void wxSoundStreamESD::WakeUpEvt(int evt)
214 {
215 m_q_filled = FALSE;
216 OnSoundEvent(evt);
217 }
218
219 // --------------------------------------------------------------------------
220 // StartProduction(): see wxSoundStream
221 // --------------------------------------------------------------------------
222 bool wxSoundStreamESD::StartProduction(int evt)
223 {
224 wxSoundFormatPcm *pcm;
225 int flag = 0;
226
227 if (!m_esd_ok) {
228 m_snderror = wxSOUND_INVDEV;
229 return FALSE;
230 }
231
232 if (!m_esd_stop)
233 StopProduction();
234
235 pcm = (wxSoundFormatPcm *)m_sndformat;
236
237 flag |= (pcm->GetBPS() == 16) ? ESD_BITS16 : ESD_BITS8;
238 flag |= (pcm->GetChannels() == 2) ? ESD_STEREO : ESD_MONO;
239
240 if ((evt & wxSOUND_OUTPUT) != 0) {
241 flag |= ESD_PLAY | ESD_STREAM;
242 m_fd_output = esd_play_stream(flag, pcm->GetSampleRate(), NULL,
243 MY_ESD_NAME);
244 }
245
246 if ((evt & wxSOUND_INPUT) != 0) {
247 flag |= ESD_RECORD | ESD_STREAM;
248 m_fd_input = esd_record_stream(flag, pcm->GetSampleRate(), NULL,
249 MY_ESD_NAME);
250 }
251
252 #ifdef __WXGTK__
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);
256 }
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);
260 }
261 #endif
262
263 m_esd_stop = FALSE;
264 m_q_filled = FALSE;
265
266 return TRUE;
267 }
268
269 // --------------------------------------------------------------------------
270 // StopProduction(): see wxSoundStream
271 // --------------------------------------------------------------------------
272 bool wxSoundStreamESD::StopProduction()
273 {
274 if (m_esd_stop)
275 return FALSE;
276
277 if (m_fd_input != -1) {
278 esd_close(m_fd_input);
279 #ifdef __WXGTK__
280 gdk_input_remove(m_tag_input);
281 #endif
282 }
283 if (m_fd_output != -1) {
284 esd_close(m_fd_output);
285 #ifdef __WXGTK__
286 gdk_input_remove(m_tag_output);
287 #endif
288 }
289
290 m_fd_input = -1;
291 m_fd_output= -1;
292 m_esd_stop = TRUE;
293 m_q_filled = TRUE;
294 return TRUE;
295 }
296
297 //
298 // Detect the closest format (The best).
299 //
300 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm *pcm)
301 {
302 wxSoundFormatPcm best_pcm;
303
304 // We change neither the number of channels nor the sample rate
305 // because ESD is clever.
306
307 best_pcm.SetSampleRate(pcm->GetSampleRate());
308 best_pcm.SetChannels(pcm->GetChannels());
309
310 // It supports 16 bits
311 if (pcm->GetBPS() >= 16)
312 best_pcm.SetBPS(16);
313 else
314 best_pcm.SetBPS(8);
315
316 best_pcm.SetOrder(wxLITTLE_ENDIAN);
317 best_pcm.Signed(TRUE);
318
319 // Finally recopy the new format
320 *pcm = best_pcm;
321 }
322
323 #endif // HAVE_ESD_H