// -------------------------------------------------------------------------- // Name: sndesd.cpp // Purpose: // Date: 08/11/1999 // Author: Guilhem Lavaux (C) 1999 // CVSID: $Id$ // -------------------------------------------------------------------------- #ifdef __GNUG__ #pragma implementation "sndesd.cpp" #endif #include #include #include #include #include #include #include "sndbase.h" #include "sndesd.h" #include "sndpcm.h" #ifdef __WXGTK__ #include #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; }