1 // -------------------------------------------------------------------------- 
   5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999 
   7 // -------------------------------------------------------------------------- 
   9 #pragma implementation "sndesd.cpp" 
  12 #include "wx/wxprec.h" 
  16     #include "wx/string.h" 
  23 // -------------------------------------------------------------------------- 
  25 // -------------------------------------------------------------------------- 
  27 #include "wx/mmedia/sndbase.h" 
  28 #include "wx/mmedia/sndesd.h" 
  29 #include "wx/mmedia/sndpcm.h" 
  31 // -------------------------------------------------------------------------- 
  33 // -------------------------------------------------------------------------- 
  36 #include <sys/types.h> 
  45 // -------------------------------------------------------------------------- 
  47 #define MY_ESD_NAME "wxWidgets/wxSoundStreamESD" 
  49 // -------------------------------------------------------------------------- 
  50 // wxSoundStreamESD: ESD sound driver 
  52 // -------------------------------------------------------------------------- 
  53 // Constructors/Destructors 
  54 // -------------------------------------------------------------------------- 
  56 wxSoundStreamESD::wxSoundStreamESD(const wxString
& hostname
) 
  59     m_snderror 
= wxSOUND_INVDEV
; 
  62     wxSoundFormatPcm pcm_default
; 
  64     // First, we make some basic test: is there ESD on this computer ? 
  67     if (hostname
.IsNull()) 
  68         m_fd_output 
= esd_play_stream(ESD_PLAY 
| ESD_STREAM
, 22050,  
  69                                       hostname
.mb_str(), MY_ESD_NAME
); 
  71         m_fd_output 
= esd_play_stream(ESD_PLAY 
| ESD_STREAM
, 22050,  
  73     if (m_fd_output 
== -1) { 
  74         // Answer: no. We return with an error. 
  75         m_snderror 
= wxSOUND_INVDEV
; 
  79     // Close this unuseful stream. 
  80     esd_close(m_fd_output
); 
  82     m_hostname 
= hostname
; 
  84     // Set the default audio format 
  85     SetSoundFormat(pcm_default
); 
  87     // Initialize some variable 
  88     m_snderror 
= wxSOUND_NOERROR
; 
  94 #endif // defined HAVE_ESD_H 
  97 wxSoundStreamESD::~wxSoundStreamESD() 
 102 #endif // defined HAVE_ESD_H 
 105 // -------------------------------------------------------------------------- 
 106 // Read several samples 
 107 // -------------------------------------------------------------------------- 
 109 wxSoundStream
& wxSoundStreamESD::Read(void *buffer
, wxUint32 len
) 
 112     m_snderror 
= wxSOUND_INVDEV
; 
 118         m_snderror 
= wxSOUND_NOTSTARTED
; 
 122     m_lastcount 
= (wxUint32
)ret 
= read(m_fd_input
, buffer
, len
); 
 125         m_snderror 
= wxSOUND_IOERROR
; 
 127         m_snderror 
= wxSOUND_NOERROR
; 
 130 #endif // defined HAVE_ESD_H 
 133 // -------------------------------------------------------------------------- 
 134 // Write several samples 
 135 // -------------------------------------------------------------------------- 
 136 wxSoundStream
& wxSoundStreamESD::Write(const void *buffer
, wxUint32 len
) 
 139     m_snderror 
= wxSOUND_INVDEV
; 
 146         m_snderror 
= wxSOUND_NOTSTARTED
; 
 150     m_lastcount 
= (wxUint32
)ret 
= write(m_fd_output
, buffer
, len
); 
 153         m_snderror 
= wxSOUND_IOERROR
; 
 155       m_snderror 
= wxSOUND_NOERROR
; 
 160 #endif // defined HAVE_ESD_H 
 163 // -------------------------------------------------------------------------- 
 164 // SetSoundFormat(): this function specifies which format we want and which 
 165 // format is available 
 166 // -------------------------------------------------------------------------- 
 167 bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase
& format
) 
 170     m_snderror 
= wxSOUND_INVDEV
; 
 173     wxSoundFormatPcm 
*pcm_format
; 
 175     if (format
.GetType() != wxSOUND_PCM
) { 
 176         m_snderror 
= wxSOUND_INVFRMT
; 
 181         m_snderror 
= wxSOUND_INVDEV
; 
 188     m_sndformat 
= format
.Clone(); 
 190         m_snderror 
= wxSOUND_MEMERROR
; 
 193     pcm_format 
= (wxSoundFormatPcm 
*)m_sndformat
; 
 195     // Detect the best format 
 196     DetectBest(pcm_format
); 
 198     m_snderror 
= wxSOUND_NOERROR
; 
 199     if (*pcm_format 
!= format
) { 
 200         m_snderror 
= wxSOUND_NOEXACT
; 
 204 #endif // defined HAVE_ESD_H 
 207 // -------------------------------------------------------------------------- 
 208 // _wxSound_OSS_CBack (internal): it is called when the driver (ESD) is 
 209 // ready for a next buffer. 
 210 // -------------------------------------------------------------------------- 
 211 #if defined(__WXGTK__) && defined(HAVE_ESD_H) 
 212 static void _wxSound_OSS_CBack(gpointer data
, int source
, 
 213                                GdkInputCondition condition
) 
 215     wxSoundStreamESD 
*esd 
= (wxSoundStreamESD 
*)data
; 
 219             esd
->WakeUpEvt(wxSOUND_INPUT
); 
 221         case GDK_INPUT_WRITE
: 
 222             esd
->WakeUpEvt(wxSOUND_OUTPUT
); 
 231 // -------------------------------------------------------------------------- 
 232 // WakeUpEvt() (internal): it is called by _wxSound_OSS_CBack to bypass the 
 234 // -------------------------------------------------------------------------- 
 235 void wxSoundStreamESD::WakeUpEvt(int evt
) 
 241 // -------------------------------------------------------------------------- 
 242 // StartProduction(): see wxSoundStream 
 243 // -------------------------------------------------------------------------- 
 244 bool wxSoundStreamESD::StartProduction(int evt
) 
 247     m_snderror 
= wxSOUND_INVDEV
; 
 250     wxSoundFormatPcm 
*pcm
; 
 254         m_snderror 
= wxSOUND_INVDEV
; 
 261     pcm 
= (wxSoundFormatPcm 
*)m_sndformat
; 
 263     flag 
|= (pcm
->GetBPS() == 16) ? ESD_BITS16 
: ESD_BITS8
; 
 264     flag 
|= (pcm
->GetChannels() == 2) ? ESD_STEREO 
: ESD_MONO
; 
 266     if ((evt 
& wxSOUND_OUTPUT
) != 0) { 
 267         flag 
|= ESD_PLAY 
| ESD_STREAM
; 
 268         m_fd_output 
= esd_play_stream(flag
, pcm
->GetSampleRate(), NULL
, 
 272     if ((evt 
& wxSOUND_INPUT
) != 0) { 
 273         flag 
|= ESD_RECORD 
| ESD_STREAM
; 
 274         m_fd_input 
= esd_record_stream(flag
, pcm
->GetSampleRate(), NULL
, 
 279     if ((evt 
& wxSOUND_OUTPUT
) != 0) { 
 280         m_tag_output 
= gdk_input_add(m_fd_output
, GDK_INPUT_WRITE
, 
 281                                      _wxSound_OSS_CBack
, (gpointer
)this); 
 283     if ((evt 
& wxSOUND_INPUT
) != 0) { 
 284         m_tag_input 
= gdk_input_add(m_fd_input
, GDK_INPUT_READ
, 
 285                                     _wxSound_OSS_CBack
, (gpointer
)this); 
 293 #endif // defined HAVE_ESD_H 
 296 // -------------------------------------------------------------------------- 
 297 // StopProduction(): see wxSoundStream 
 298 // -------------------------------------------------------------------------- 
 299 bool wxSoundStreamESD::StopProduction() 
 302     m_snderror 
= wxSOUND_INVDEV
; 
 308     if (m_fd_input 
!= -1) { 
 309         esd_close(m_fd_input
); 
 311         gdk_input_remove(m_tag_input
); 
 314     if (m_fd_output 
!= -1) { 
 315         esd_close(m_fd_output
); 
 317         gdk_input_remove(m_tag_output
); 
 326 #endif // defined HAVE_ESD_H 
 330 // Detect the closest format (The best). 
 332 void wxSoundStreamESD::DetectBest(wxSoundFormatPcm 
*pcm
) 
 335     m_snderror 
= wxSOUND_INVDEV
; 
 338     wxSoundFormatPcm best_pcm
; 
 340     // We change neither the number of channels nor the sample rate 
 341     // because ESD is clever. 
 343     best_pcm
.SetSampleRate(pcm
->GetSampleRate()); 
 344     best_pcm
.SetChannels(pcm
->GetChannels()); 
 346     // It supports 16 bits 
 347     if (pcm
->GetBPS() >= 16) 
 352     best_pcm
.SetOrder(wxLITTLE_ENDIAN
); 
 353     best_pcm
.Signed(true); 
 355     // Finally recopy the new format 
 357 #endif // defined HAVE_ESD_H