]> git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia2/lib/sndesd.cpp
CanRead() now restores the stream to its previous state (potential
[wxWidgets.git] / utils / wxMMedia2 / lib / 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 <sys/types.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15 #include <wx/defs.h>
16 #include <wx/string.h>
17 #include <esd.h>
18 #include "sndbase.h"
19 #include "sndesd.h"
20 #include "sndpcm.h"
21 #ifdef __WXGTK__
22 #include <gdk/gdk.h>
23 #endif
24
25 #define MY_ESD_NAME "wxWindows/wxSoundStreamESD"
26
27 wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
28 {
29 wxSoundFormatPcm pcm_default;
30
31 m_fd = esd_monitor_stream(ESD_MONO | ESD_BITS8 | ESD_RECORD, 22050,
32 hostname.mb_str(), MY_ESD_NAME);
33
34 if (m_fd == -1) {
35 m_snderror = wxSOUND_INVDEV;
36 return;
37 }
38
39 esd_close(m_fd);
40
41 m_hostname = hostname;
42
43 SetSoundFormat(pcm_default);
44
45 m_snderror = wxSOUND_NOERR;
46 m_esd_stop = TRUE;
47 }
48
49 wxSoundStreamESD::~wxSoundStreamESD()
50 {
51 if (m_fd > 0)
52 esd_close(m_fd);
53 }
54
55 wxSoundStream& wxSoundStreamESD::Read(void *buffer, size_t len)
56 {
57 int ret;
58
59 m_lastcount = (size_t)ret = read(m_fd, buffer, len);
60
61 if (ret < 0)
62 m_snderror = wxSOUND_IOERR;
63 else
64 m_snderror = wxSOUND_NOERR;
65
66 return *this;
67 }
68
69 wxSoundStream& wxSoundStreamESD::Write(const void *buffer, size_t len)
70 {
71 int ret;
72
73 m_lastcount = (size_t)ret = write(m_fd, buffer, len);
74
75 if (ret < 0)
76 m_snderror = wxSOUND_IOERR;
77 else
78 m_snderror = wxSOUND_NOERR;
79
80 return *this;
81 }
82
83 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
84 {
85 wxSoundFormatPcm *pcm_format;
86
87 if (format.GetType() != wxSOUND_PCM) {
88 m_snderror = wxSOUND_INVFRMT;
89 return FALSE;
90 }
91
92 if (m_fd == -1) {
93 m_snderror = wxSOUND_INVDEV;
94 return FALSE;
95 }
96
97 if (m_sndformat)
98 delete m_sndformat;
99
100 m_sndformat = format.Clone();
101 if (!m_sndformat) {
102 m_snderror = wxSOUND_MEMERR;
103 return FALSE;
104 }
105 pcm_format = (wxSoundFormatPcm *)m_sndformat;
106
107 // Detect the best format
108 DetectBest(pcm_format);
109
110 m_snderror = wxSOUND_NOERR;
111 if (*pcm_format != format) {
112 m_snderror = wxSOUND_NOTEXACT;
113 return FALSE;
114 }
115 return TRUE;
116 }
117
118 #ifdef __WXGTK__
119 static void _wxSound_OSS_CBack(gpointer data, int source,
120 GdkInputCondition condition)
121 {
122 wxSoundStreamESD *esd = (wxSoundStreamESD *)data;
123
124 switch (condition) {
125 case GDK_INPUT_READ:
126 esd->WakeUpEvt(wxSOUND_INPUT);
127 break;
128 case GDK_INPUT_WRITE:
129 esd->WakeUpEvt(wxSOUND_OUTPUT);
130 break;
131 default:
132 break;
133 }
134 }
135 #endif
136
137 void wxSoundStreamESD::WakeUpEvt(int evt)
138 {
139 OnSoundEvent(evt);
140 }
141
142 bool wxSoundStreamESD::StartProduction(int evt)
143 {
144 wxSoundFormatPcm *pcm;
145 int flag = 0;
146
147 if (!m_esd_stop)
148 StopProduction();
149
150 pcm = (wxSoundFormatPcm *)m_sndformat;
151
152 flag |= (pcm->GetBPS() == 16) ? ESD_BITS16 : ESD_BITS8;
153 flag |= (pcm->GetChannels() == 2) ? ESD_STEREO : ESD_MONO;
154
155 if (evt == wxSOUND_OUTPUT) {
156 flag |= ESD_PLAY | ESD_STREAM;
157 m_fd = esd_play_stream(flag, pcm->GetSampleRate(), m_hostname.mb_str(),
158 MY_ESD_NAME);
159 } else {
160 flag |= ESD_RECORD | ESD_STREAM;
161 m_fd = esd_record_stream(flag, pcm->GetSampleRate(), m_hostname.mb_str(),
162 MY_ESD_NAME);
163 }
164
165 #ifdef __WXGTK__
166 if (evt == wxSOUND_OUTPUT)
167 m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this);
168 else
169 m_tag = gdk_input_add(m_fd, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
170 #endif
171
172 m_esd_stop = FALSE;
173
174 return TRUE;
175 }
176
177 bool wxSoundStreamESD::StopProduction()
178 {
179 if (m_esd_stop)
180 return FALSE;
181
182 gdk_input_remove(m_tag);
183 esd_close(m_fd);
184 m_esd_stop = TRUE;
185 return TRUE;
186 }
187
188 //
189 // Detect the closest format (The best).
190 //
191 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm *pcm)
192 {
193 wxSoundFormatPcm best_pcm;
194
195 // We change neither the number of channels nor the sample rate
196
197 best_pcm.SetSampleRate(pcm->GetSampleRate());
198 best_pcm.SetChannels(pcm->GetChannels());
199
200 // It supports 16 bits
201 if (pcm->GetBPS() == 16)
202 best_pcm.SetBPS(16);
203
204 best_pcm.SetOrder(wxLITTLE_ENDIAN);
205 best_pcm.Signed(TRUE);
206
207 // Finally recopy the new format
208 *pcm = best_pcm;
209 }