]>
Commit | Line | Data |
---|---|---|
526ddb13 GL |
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 | ||
56dc1ffd GL |
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); | |
526ddb13 GL |
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; | |
56dc1ffd | 48 | m_q_filled = TRUE; |
526ddb13 GL |
49 | } |
50 | ||
51 | wxSoundStreamESD::~wxSoundStreamESD() | |
52 | { | |
53 | if (m_fd > 0) | |
54 | esd_close(m_fd); | |
55 | } | |
56 | ||
0662cd32 | 57 | wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len) |
526ddb13 GL |
58 | { |
59 | int ret; | |
60 | ||
0662cd32 | 61 | m_lastcount = (wxUint32)ret = read(m_fd, buffer, len); |
526ddb13 GL |
62 | |
63 | if (ret < 0) | |
64 | m_snderror = wxSOUND_IOERR; | |
65 | else | |
66 | m_snderror = wxSOUND_NOERR; | |
67 | ||
68 | return *this; | |
69 | } | |
70 | ||
0662cd32 | 71 | wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len) |
526ddb13 GL |
72 | { |
73 | int ret; | |
74 | ||
0662cd32 | 75 | m_lastcount = (wxUint32)ret = write(m_fd, buffer, len); |
526ddb13 GL |
76 | |
77 | if (ret < 0) | |
78 | m_snderror = wxSOUND_IOERR; | |
79 | else | |
80 | m_snderror = wxSOUND_NOERR; | |
81 | ||
56dc1ffd GL |
82 | m_q_filled = TRUE; |
83 | ||
526ddb13 GL |
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) { | |
27259273 | 116 | m_snderror = wxSOUND_NOEXACT; |
526ddb13 GL |
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 | { | |
56dc1ffd | 143 | m_q_filled = FALSE; |
526ddb13 GL |
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; | |
56dc1ffd | 162 | m_fd = esd_play_stream(flag, pcm->GetSampleRate(), NULL, |
526ddb13 GL |
163 | MY_ESD_NAME); |
164 | } else { | |
165 | flag |= ESD_RECORD | ESD_STREAM; | |
56dc1ffd | 166 | m_fd = esd_record_stream(flag, pcm->GetSampleRate(), NULL, |
526ddb13 GL |
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; | |
56dc1ffd | 178 | m_q_filled = FALSE; |
526ddb13 GL |
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; | |
56dc1ffd | 191 | m_q_filled = TRUE; |
526ddb13 GL |
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 | } |