]> git.saurik.com Git - wxWidgets.git/blame - utils/wxMMedia2/lib/sndesd.cpp
CanRead() now restores the stream to its previous state (potential
[wxWidgets.git] / utils / wxMMedia2 / lib / sndesd.cpp
CommitLineData
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
27wxSoundStreamESD::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
49wxSoundStreamESD::~wxSoundStreamESD()
50{
51 if (m_fd > 0)
52 esd_close(m_fd);
53}
54
55wxSoundStream& 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
69wxSoundStream& 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
83bool 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__
119static 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
137void wxSoundStreamESD::WakeUpEvt(int evt)
138{
139 OnSoundEvent(evt);
140}
141
142bool 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
177bool 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//
191void 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}