Changed size_t to wxUint32 Added support for G72X WAV format multi-codec handling git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3508 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			210 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			210 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// --------------------------------------------------------------------------
 | 
						|
// Name: sndesd.cpp
 | 
						|
// Purpose:
 | 
						|
// Date: 08/11/1999
 | 
						|
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
 | 
						|
// CVSID: $Id$
 | 
						|
// --------------------------------------------------------------------------
 | 
						|
#ifdef __GNUG__
 | 
						|
#pragma implementation "sndesd.cpp"
 | 
						|
#endif
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <wx/defs.h>
 | 
						|
#include <wx/string.h>
 | 
						|
#include <esd.h>
 | 
						|
#include "sndbase.h"
 | 
						|
#include "sndesd.h"
 | 
						|
#include "sndpcm.h"
 | 
						|
#ifdef __WXGTK__
 | 
						|
#include <gdk/gdk.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#define MY_ESD_NAME "wxWindows/wxSoundStreamESD"
 | 
						|
 | 
						|
wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname)
 | 
						|
{
 | 
						|
  wxSoundFormatPcm pcm_default;
 | 
						|
 | 
						|
  m_fd = esd_monitor_stream(ESD_MONO | ESD_BITS8 | ESD_RECORD, 22050, 
 | 
						|
                            hostname.mb_str(), MY_ESD_NAME);
 | 
						|
 | 
						|
  if (m_fd == -1) {
 | 
						|
    m_snderror = wxSOUND_INVDEV;
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  esd_close(m_fd);
 | 
						|
 
 | 
						|
  m_hostname = hostname;
 | 
						|
 | 
						|
  SetSoundFormat(pcm_default);
 | 
						|
 | 
						|
  m_snderror = wxSOUND_NOERR;
 | 
						|
  m_esd_stop = TRUE;
 | 
						|
}
 | 
						|
 | 
						|
wxSoundStreamESD::~wxSoundStreamESD()
 | 
						|
{
 | 
						|
  if (m_fd > 0)
 | 
						|
    esd_close(m_fd);
 | 
						|
}
 | 
						|
 | 
						|
wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len)
 | 
						|
{
 | 
						|
  int ret;
 | 
						|
 | 
						|
  m_lastcount = (wxUint32)ret = read(m_fd, buffer, len);
 | 
						|
 | 
						|
  if (ret < 0)
 | 
						|
    m_snderror = wxSOUND_IOERR;
 | 
						|
  else
 | 
						|
    m_snderror = wxSOUND_NOERR;
 | 
						|
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len)
 | 
						|
{
 | 
						|
  int ret;
 | 
						|
 | 
						|
  m_lastcount = (wxUint32)ret = write(m_fd, buffer, len);
 | 
						|
 | 
						|
  if (ret < 0)
 | 
						|
    m_snderror = wxSOUND_IOERR;
 | 
						|
  else
 | 
						|
    m_snderror = wxSOUND_NOERR;
 | 
						|
 | 
						|
  return *this;
 | 
						|
}
 | 
						|
 | 
						|
bool wxSoundStreamESD::SetSoundFormat(const wxSoundFormatBase& format)
 | 
						|
{
 | 
						|
  wxSoundFormatPcm *pcm_format;
 | 
						|
 | 
						|
  if (format.GetType() != wxSOUND_PCM) {
 | 
						|
    m_snderror = wxSOUND_INVFRMT;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (m_fd == -1) {
 | 
						|
    m_snderror = wxSOUND_INVDEV;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (m_sndformat)
 | 
						|
    delete m_sndformat;
 | 
						|
 | 
						|
  m_sndformat = format.Clone();
 | 
						|
  if (!m_sndformat) {
 | 
						|
    m_snderror = wxSOUND_MEMERR;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
  pcm_format = (wxSoundFormatPcm *)m_sndformat;
 | 
						|
 | 
						|
  // Detect the best format
 | 
						|
  DetectBest(pcm_format);
 | 
						|
 | 
						|
  m_snderror = wxSOUND_NOERR;
 | 
						|
  if (*pcm_format != format) {
 | 
						|
    m_snderror = wxSOUND_NOTEXACT;
 | 
						|
    return FALSE;
 | 
						|
  }
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef __WXGTK__
 | 
						|
static void _wxSound_OSS_CBack(gpointer data, int source,
 | 
						|
                               GdkInputCondition condition)
 | 
						|
{
 | 
						|
  wxSoundStreamESD *esd = (wxSoundStreamESD *)data;
 | 
						|
 | 
						|
  switch (condition) {
 | 
						|
  case GDK_INPUT_READ:
 | 
						|
    esd->WakeUpEvt(wxSOUND_INPUT);
 | 
						|
    break;
 | 
						|
  case GDK_INPUT_WRITE:
 | 
						|
    esd->WakeUpEvt(wxSOUND_OUTPUT);
 | 
						|
    break;
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
void wxSoundStreamESD::WakeUpEvt(int evt)
 | 
						|
{
 | 
						|
  OnSoundEvent(evt);
 | 
						|
}
 | 
						|
 | 
						|
bool wxSoundStreamESD::StartProduction(int evt)
 | 
						|
{
 | 
						|
  wxSoundFormatPcm *pcm;
 | 
						|
  int flag = 0;
 | 
						|
 | 
						|
  if (!m_esd_stop)
 | 
						|
    StopProduction();
 | 
						|
 | 
						|
  pcm = (wxSoundFormatPcm *)m_sndformat;
 | 
						|
 | 
						|
  flag |= (pcm->GetBPS() == 16) ? ESD_BITS16 : ESD_BITS8;
 | 
						|
  flag |= (pcm->GetChannels() == 2) ? ESD_STEREO : ESD_MONO;
 | 
						|
 | 
						|
  if (evt == wxSOUND_OUTPUT) {
 | 
						|
    flag |= ESD_PLAY | ESD_STREAM;
 | 
						|
    m_fd = esd_play_stream(flag, pcm->GetSampleRate(), m_hostname.mb_str(),
 | 
						|
			   MY_ESD_NAME);
 | 
						|
  } else {
 | 
						|
    flag |= ESD_RECORD | ESD_STREAM;
 | 
						|
    m_fd = esd_record_stream(flag, pcm->GetSampleRate(), m_hostname.mb_str(),
 | 
						|
                             MY_ESD_NAME);
 | 
						|
  }
 | 
						|
 | 
						|
#ifdef __WXGTK__
 | 
						|
  if (evt == wxSOUND_OUTPUT)
 | 
						|
    m_tag = gdk_input_add(m_fd, GDK_INPUT_WRITE, _wxSound_OSS_CBack, (gpointer)this);
 | 
						|
  else
 | 
						|
    m_tag = gdk_input_add(m_fd, GDK_INPUT_READ, _wxSound_OSS_CBack, (gpointer)this);
 | 
						|
#endif
 | 
						|
 | 
						|
  m_esd_stop = FALSE;
 | 
						|
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
bool wxSoundStreamESD::StopProduction()
 | 
						|
{
 | 
						|
  if (m_esd_stop)
 | 
						|
    return FALSE;
 | 
						|
 | 
						|
  gdk_input_remove(m_tag);
 | 
						|
  esd_close(m_fd);
 | 
						|
  m_esd_stop = TRUE;
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
//
 | 
						|
// Detect the closest format (The best).
 | 
						|
//
 | 
						|
void wxSoundStreamESD::DetectBest(wxSoundFormatPcm *pcm)
 | 
						|
{
 | 
						|
  wxSoundFormatPcm best_pcm;
 | 
						|
 | 
						|
  // We change neither the number of channels nor the sample rate
 | 
						|
 | 
						|
  best_pcm.SetSampleRate(pcm->GetSampleRate());
 | 
						|
  best_pcm.SetChannels(pcm->GetChannels());
 | 
						|
 | 
						|
  // It supports 16 bits
 | 
						|
  if (pcm->GetBPS() == 16)
 | 
						|
    best_pcm.SetBPS(16);
 | 
						|
 | 
						|
  best_pcm.SetOrder(wxLITTLE_ENDIAN);
 | 
						|
  best_pcm.Signed(TRUE);
 | 
						|
 | 
						|
  // Finally recopy the new format
 | 
						|
  *pcm = best_pcm;
 | 
						|
}
 |