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