// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
// CVSID: $Id$
// --------------------------------------------------------------------------
+#include <wx/wxprec.h>
+
+#ifndef WX_PRECOMP
#include <wx/stream.h>
+#endif
+
#include "sndbase.h"
#include "sndcodec.h"
#include "sndfile.h"
#include "sndcpcm.h"
#include "sndulaw.h"
+#include "sndg72x.h"
// --------------------------------------------------------------------------
// Sound codec router
+// A very important class: it ensures that everybody is satisfied.
+// It is supposed to create as many codec as it is necessary to transform
+// a signal in a specific format in an another.
// --------------------------------------------------------------------------
-
wxSoundRouterStream::wxSoundRouterStream(wxSoundStream& sndio)
: wxSoundStreamCodec(sndio)
{
delete m_router;
}
-wxSoundStream& wxSoundRouterStream::Read(void *buffer, size_t len)
+// --------------------------------------------------------------------------
+// Read(void *buffer, wxUint32 len): It reads data synchronously. See sndbase.h
+// for possible errors and behaviours ...
+// --------------------------------------------------------------------------
+wxSoundStream& wxSoundRouterStream::Read(void *buffer, wxUint32 len)
{
if (m_router) {
m_router->Read(buffer, len);
return *this;
}
-wxSoundStream& wxSoundRouterStream::Write(const void *buffer, size_t len)
+// --------------------------------------------------------------------------
+// Write(const void *buffer, wxUint32 len): It writes data synchronously
+// --------------------------------------------------------------------------
+wxSoundStream& wxSoundRouterStream::Write(const void *buffer, wxUint32 len)
{
if (m_router) {
m_router->Write(buffer, len);
return *this;
}
+// --------------------------------------------------------------------------
+// SetSoundFormat(const wxSoundFormatBase& format) first tries to setup the
+// sound driver using the specified format. If this fails, it uses personnal
+// codec converters: for the moment there is a PCM converter (PCM to PCM:
+// with optional resampling, ...), an ULAW converter (ULAW to PCM), a G72X
+// converter (G72X to PCM). If nothing works, it returns FALSE.
+// --------------------------------------------------------------------------
bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format)
{
if (m_router)
m_router = new wxSoundStreamUlaw(*m_sndio);
m_router->SetSoundFormat(format);
break;
+ case wxSOUND_G72X:
+ m_router = new wxSoundStreamG72X(*m_sndio);
+ m_router->SetSoundFormat(format);
+ break;
}
wxSoundStream::SetSoundFormat(m_router->GetSoundFormat());
return TRUE;
}
+// --------------------------------------------------------------------------
+// GetBestSize() returns the specific best buffer size a sound driver
+// can manage. It means that it will be easier for it to manage the buffer
+// and so it will be faster and in some case more accurate for real-time event.
+// --------------------------------------------------------------------------
+wxUint32 wxSoundRouterStream::GetBestSize() const
+{
+ if (m_router)
+ return m_router->GetBestSize();
+ else
+ return m_sndio->GetBestSize();
+}
+
+// --------------------------------------------------------------------------
+// StartProduction(int evt). See sndbase.h
+// --------------------------------------------------------------------------
bool wxSoundRouterStream::StartProduction(int evt)
{
if (!m_router) {
return FALSE;
}
+// --------------------------------------------------------------------------
+// StopProduction(). See sndbase.h
+// --------------------------------------------------------------------------
bool wxSoundRouterStream::StopProduction()
{
if (!m_router) {
if (!PrepareToPlay())
return FALSE;
+ m_state = wxSOUND_FILE_PLAYING;
+
if (!StartProduction(wxSOUND_OUTPUT))
return FALSE;
- m_state = wxSOUND_FILE_PLAYING;
return TRUE;
}
if (!PrepareToRecord(time))
return FALSE;
- m_len = m_sndformat->GetByteFromTime(time);
+ m_len = m_sndformat->GetBytesFromTime(time);
+ m_state = wxSOUND_FILE_RECORDING;
if (!StartProduction(wxSOUND_INPUT))
return FALSE;
- m_state = wxSOUND_FILE_RECORDING;
return TRUE;
}
m_state = wxSOUND_FILE_STOPPED;
return FALSE;
}
+
+ if (m_input)
+ m_input->SeekI(0, wxFromStart);
+
+ if (m_output)
+ m_output->SeekO(0, wxFromStart);
- // TODO reset counter
m_state = wxSOUND_FILE_STOPPED;
return TRUE;
}
return TRUE;
}
-wxSoundStream& wxSoundFileStream::Read(void *buffer, size_t len)
+wxSoundStream& wxSoundFileStream::Read(void *buffer, wxUint32 len)
{
m_lastcount = GetData(buffer, len);
return *this;
}
-wxSoundStream& wxSoundFileStream::Write(const void *buffer, size_t len)
+wxSoundStream& wxSoundFileStream::Write(const void *buffer, wxUint32 len)
{
m_lastcount = PutData(buffer, len);
return *this;
void wxSoundFileStream::OnSoundEvent(int evt)
{
- size_t len = m_sndio->GetBestSize();
- char buffer[m_sndio->GetBestSize()];
+ wxUint32 len = m_codec.GetBestSize();
+ char *buffer;
+ buffer = new char[len];
wxSoundStream::OnSoundEvent(evt);
- switch(evt) {
- case wxSOUND_INPUT:
- if (len > m_len)
- len = m_len;
-
- len = m_codec.Read(buffer, len).GetLastAccess();
- PutData(buffer, len);
- m_len -= len;
- if (m_len == 0) {
- Stop();
- return;
+ while (!m_sndio->QueueFilled()) {
+ switch(evt) {
+ case wxSOUND_INPUT:
+ if (len > m_len)
+ len = m_len;
+
+ len = m_codec.Read(buffer, len).GetLastAccess();
+ PutData(buffer, len);
+ m_len -= len;
+ if (m_len == 0) {
+ Stop();
+ delete[] buffer;
+ return;
+ }
+ break;
+ case wxSOUND_OUTPUT:
+ len = GetData(buffer, len);
+ if (len == 0) {
+ Stop();
+ delete[] buffer;
+ return;
+ }
+ m_codec.Write(buffer, len);
+ break;
}
- break;
- case wxSOUND_OUTPUT:
- len = GetData(buffer, len);
- if (len == 0) {
- Stop();
- return;
- }
- m_codec.Write(buffer, len);
- break;
}
+ delete[] buffer;
}
bool wxSoundFileStream::SetSoundFormat(const wxSoundFormatBase& format)