wxMMedia doc updates

wxMMedia compilation fixes
OGL and STC makefile build fixes


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7528 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Guilhem Lavaux
2000-06-04 08:38:36 +00:00
parent b97a2c5385
commit c42b1de68a
23 changed files with 502 additions and 152 deletions

View File

@@ -214,15 +214,30 @@ been set. In all other cases, you must return FALSE.
\membersection{wxSoundFileStream::RepositionStream}\label{wxsoundfilestreamrepositionstream} \membersection{wxSoundFileStream::RepositionStream}\label{wxsoundfilestreamrepositionstream}
\func{bool}{RepositionStream}{\param{wxUint32 }{position}} \func{bool}{RepositionStream}{\param{wxUint32 }{position}}
This is called by wxSoundFileStream::SetPosition to seek the input stream
to the right position. This must be overidden by the file codec class.
The position is relative to the beginning of the samples.
If it is impossible (as for a piped input stream), you must return FALSE.
\membersection{wxSoundFileStream::FinishPreparation}\label{wxsoundfilestreamfinishpreparation} \membersection{wxSoundFileStream::FinishPreparation}\label{wxsoundfilestreamfinishpreparation}
\func{void}{FinishPreparation}{\param{wxUint32 }{len}} \func{void}{FinishPreparation}{\param{wxUint32 }{len}}
This is an internal function but it must called by the file codec class when
the "playing" preparation is finished and you know the size of the stream.
If it is an {\it infinite} stream, you should set this to wxSOUND\_INFINITE\_TIME.
\membersection{wxSoundFileStream::GetData}\label{wxsoundfilestreamgetdata} \membersection{wxSoundFileStream::GetData}\label{wxsoundfilestreamgetdata}
\func{wxUint32}{GetData}{\param{void* }{buffer}, \param{wxUint32 }{len}} \func{wxUint32}{GetData}{\param{void* }{buffer}, \param{wxUint32 }{len}}
This is called by wxSoundFileStream when it needs to get new sound data to
send to the device driver (or to a conversion codec). This must be eventually
overidden by the file codec class. The default behaviour is simply to read from
the input stream.
\membersection{wxSoundFileStream::PutData}\label{wxsoundfilestreamputdata} \membersection{wxSoundFileStream::PutData}\label{wxsoundfilestreamputdata}
\func{wxUint32}{PutData}{\param{const void* }{buffer}, \param{wxUint32 }{len}} \func{wxUint32}{PutData}{\param{const void* }{buffer}, \param{wxUint32 }{len}}
This is called by wxSoundFileStream when it needs to put new sound data received
from the device driver (or from a conversion codec). This must be eventually
overidden by the file codec class. The default behaviour is simply to write to
the input stream.

View File

@@ -6,8 +6,8 @@
\section{\class{wxSoundRouterStream}}\label{wxsoundrouterstream} \section{\class{wxSoundRouterStream}}\label{wxsoundrouterstream}
This is the router "codec" class. It should do codec routing when the device
Codec router class driver does not deal with a format.
\wxheading{Derived from} \wxheading{Derived from}
@@ -17,43 +17,21 @@ Codec router class
\latexignore{\rtfignore{\wxheading{Members}}} \latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxSoundRouterStream::wxSoundRouterStream}\label{wxsoundrouterstreamwxsoundrouterstream} \membersection{wxSoundRouterStream::wxSoundRouterStream}\label{wxsoundrouterstreamwxsoundrouterstream}
\func{}{wxSoundRouterStream}{\param{wxSoundStream\& }{sndio}} \func{}{wxSoundRouterStream}{\param{wxSoundStream\& }{sndio}}
\helpref{wxSoundCodec}{wxsoundcodec}
\membersection{wxSoundRouterStream::\destruct{wxSoundRouterStream}}\label{wxsoundrouterstreamdtor} \membersection{wxSoundRouterStream::\destruct{wxSoundRouterStream}}\label{wxsoundrouterstreamdtor}
\func{}{\destruct{wxSoundRouterStream}}{\void} \func{}{\destruct{wxSoundRouterStream}}{\void}
Destructor.
\membersection{wxSoundRouterStream::Read}\label{wxsoundrouterstreamread}
\func{wxSoundStream\&}{Read}{\param{void* }{buffer}, \param{wxUint32 }{len}}
\membersection{wxSoundRouterStream::Write}\label{wxsoundrouterstreamwrite}
\func{wxSoundStream\&}{Write}{\param{const void* }{buffer}, \param{wxUint32 }{len}}
\membersection{wxSoundRouterStream::SetSoundFormat}\label{wxsoundrouterstreamsetsoundformat} \membersection{wxSoundRouterStream::SetSoundFormat}\label{wxsoundrouterstreamsetsoundformat}
\func{bool}{SetSoundFormat}{\param{const wxSoundFormatBase\& }{format}} \func{bool}{SetSoundFormat}{\param{const wxSoundFormatBase\& }{format}}
SetSoundFormat will first try to setup the device driver with the specified
\membersection{wxSoundRouterStream::StartProduction}\label{wxsoundrouterstreamstartproduction} format. If this fails, it will try to find a codec which will convert the
input format to a valid format for the device driver. It uses an internal
\func{bool}{StartProduction}{\param{int }{evt}} codec database.
\membersection{wxSoundRouterStream::StopProduction}\label{wxsoundrouterstreamstopproduction}
\func{bool}{StopProduction}{\void}
\membersection{wxSoundRouterStream::GetBestSize}\label{wxsoundrouterstreamgetbestsize}
\constfunc{wxUint32}{GetBestSize}{\void}

View File

@@ -27,7 +27,7 @@ class WXDLLEXPORT wxCDAudio : public wxObject {
public: public:
typedef enum { PLAYING, PAUSED, STOPPED } CDstatus; typedef enum { PLAYING, PAUSED, STOPPED } CDstatus;
// Table of contents manager // Table of contents manager
class CDtoc { class WXDLLEXPORT CDtoc {
protected: protected:
wxCDtime *tracks_time, *tracks_pos; wxCDtime *tracks_time, *tracks_pos;
wxCDtime total_time; wxCDtime total_time;

View File

@@ -22,7 +22,7 @@
// AIFF codec // AIFF codec
// //
class wxSoundAiff: public wxSoundFileStream { class WXDLLEXPORT wxSoundAiff: public wxSoundFileStream {
public: public:
wxSoundAiff(wxInputStream& stream, wxSoundStream& io_sound); wxSoundAiff(wxInputStream& stream, wxSoundStream& io_sound);
wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound); wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound);

View File

@@ -112,7 +112,7 @@ class WXDLLEXPORT wxSoundFormatBase {
// Base class for sound streams // Base class for sound streams
// //
class wxSoundStream { class WXDLLEXPORT wxSoundStream {
public: public:
wxSoundStream(); wxSoundStream();
virtual ~wxSoundStream(); virtual ~wxSoundStream();

View File

@@ -15,7 +15,7 @@
#include "wx/defs.h" #include "wx/defs.h"
#include "wx/mmedia/sndbase.h" #include "wx/mmedia/sndbase.h"
class wxSoundStreamCodec: public wxSoundStream { class WXDLLEXPORT wxSoundStreamCodec: public wxSoundStream {
public: public:
wxSoundStreamCodec(wxSoundStream& snd_io); wxSoundStreamCodec(wxSoundStream& snd_io);
~wxSoundStreamCodec(); ~wxSoundStreamCodec();

View File

@@ -20,7 +20,7 @@
// PCM converter class // PCM converter class
// //
class wxSoundStreamPcm: public wxSoundStreamCodec { class WXDLLEXPORT wxSoundStreamPcm: public wxSoundStreamCodec {
public: public:
typedef void (*ConverterType)(const void *buf_in, void *buf_out, typedef void (*ConverterType)(const void *buf_in, void *buf_out,
wxUint32 len); wxUint32 len);

View File

@@ -5,8 +5,8 @@
// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 2000 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 2000
// CVSID: $Id$ // CVSID: $Id$
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
#ifndef _WX_SNDULAW_H #ifndef _WX_SNDMSAD_H
#define _WX_SNDULAW_H #define _WX_SNDMSAD_H
#ifdef __GNUG__ #ifdef __GNUG__
#pragma interface "sndmsad.h" #pragma interface "sndmsad.h"
@@ -17,26 +17,30 @@
#include "wx/mmedia/sndcodec.h" #include "wx/mmedia/sndcodec.h"
#include "wx/mmedia/sndbase.h" #include "wx/mmedia/sndbase.h"
WX_DEFINE_EXPORTED_ARRAY(wxUint16, wxMSAdpcmCoeffs); WX_DEFINE_EXPORTED_ARRAY(wxInt16, wxMSAdpcmCoeffs);
// //
// MSADPCM format // MSADPCM format
// //
class WXDLLEXPORT wxSoundFormatMSAdpcm: public wxSoundFormatBase { class WXDLLEXPORT wxSoundFormatMSAdpcm: public wxSoundFormatBase {
public: public:
wxSoundFormatMSAdpcm(); wxSoundFormatMSAdpcm();
~wxSoundFormatMSAdpcm(); ~wxSoundFormatMSAdpcm();
void SetSampleRate(wxUint32 srate); void SetSampleRate(wxUint32 srate);
wxUint32 GetSampleRate() const; wxUint32 GetSampleRate() const;
void SetSamplesBlock(wxUint16 sampblock); void SetCoefs(wxInt16 **coefs, wxUint16 ncoefs, wxUint16 coefs_len);
wxUint16 GetSamplesBlock() const; void GetCoefs(wxInt16 **&coefs, wxUint16& ncoefs,
wxUint16& coefs_len) const;
void SetCoefs(wxMSAdpcmCoefs& coefs); void SetBlockSize(wxUint16 block_size);
wxMSAdpcmCoefs& GetCoefs() const; wxUint16 GetBlockSize() const;
wxSoundFormatType GetType() const { return wxSOUND_ULAW; } void SetChannels(wxUint16 channels);
wxUint16 GetChannels() const;
wxSoundFormatType GetType() const { return wxSOUND_MSADPCM; }
wxSoundFormatBase *Clone() const; wxSoundFormatBase *Clone() const;
wxUint32 GetTimeFromBytes(wxUint32 bytes) const; wxUint32 GetTimeFromBytes(wxUint32 bytes) const;
@@ -44,19 +48,21 @@ class WXDLLEXPORT wxSoundFormatMSAdpcm: public wxSoundFormatBase {
bool operator !=(const wxSoundFormatBase& frmt2) const; bool operator !=(const wxSoundFormatBase& frmt2) const;
protected: protected:
wxUint32 m_srate; wxUint32 m_srate, m_nchannels;
wxMSAdpcmCoefs *m_coefs; wxInt16 **m_coefs;
wxUint16 m_ncoefs, m_coefs_len;
wxUint16 m_block_size;
}; };
// //
// MS ADPCM converter class // MS ADPCM converter class
// //
class WXDLLEXPORT wxSoundRouterStream; class WXDLLEXPORT wxSoundRouterStream;
class WXDLLEXPORT wxSoundStreamAdpcm: public wxSoundStreamCodec { class WXDLLEXPORT wxSoundStreamMSAdpcm: public wxSoundStreamCodec {
public: public:
wxSoundStreamAdpcm(wxSoundStream& sndio); wxSoundStreamMSAdpcm(wxSoundStream& sndio);
~wxSoundStreamAdpcm(); ~wxSoundStreamMSAdpcm();
wxSoundStream& Read(void *buffer, wxUint32 len); wxSoundStream& Read(void *buffer, wxUint32 len);
wxSoundStream& Write(const void *buffer, wxUint32 len); wxSoundStream& Write(const void *buffer, wxUint32 len);
@@ -67,6 +73,32 @@ public:
protected: protected:
wxSoundRouterStream *m_router; wxSoundRouterStream *m_router;
typedef struct {
wxInt32 predictor;
wxInt16 samp1;
wxInt16 samp2;
wxInt16 coeff[2];
wxInt32 iDelta;
} AdpcmState;
AdpcmState m_state[1];
bool m_got_header;
bool m_stereo;
wxInt16 **m_coefs;
wxUint16 m_block_size;
wxUint16 m_ncoefs;
wxUint16 m_next_block;
protected:
wxUint32 DecodeMonoADPCM(const void *in_buffer, void *out_buffer,
wxUint32 in_len);
wxUint32 DecodeStereoADPCM(const void *in_buffer, void *out_buffer,
wxUint32 in_len);
void Nibble(wxInt8 nyb,
AdpcmState *state,
wxInt16 **out_buffer);
}; };
#endif #endif

View File

@@ -21,7 +21,7 @@
// OSS output class // OSS output class
// //
class wxSoundStreamOSS : public wxSoundStream { class WXDLLEXPORT wxSoundStreamOSS : public wxSoundStream {
public: public:
wxSoundStreamOSS(const wxString& dev_name = wxT("/dev/dsp")); wxSoundStreamOSS(const wxString& dev_name = wxT("/dev/dsp"));
~wxSoundStreamOSS(); ~wxSoundStreamOSS();

View File

@@ -42,12 +42,18 @@ protected:
wxUint32 GetData(void *buffer, wxUint32 len); wxUint32 GetData(void *buffer, wxUint32 len);
wxUint32 PutData(const void *buffer, wxUint32 len); wxUint32 PutData(const void *buffer, wxUint32 len);
bool HandleOutputPCM(wxDataInputStream& data, wxUint16 channels, bool HandleOutputPCM(wxDataInputStream& data, wxUint32 len,
wxUint32 sample_fq, wxUint32 byte_p_sec, wxUint16 channels, wxUint32 sample_fq,
wxUint16 byte_p_spl, wxUint16 bits_p_spl); wxUint32 byte_p_sec, wxUint16 byte_p_spl,
bool HandleOutputG721(wxDataInputStream& data, wxUint16 channels, wxUint16 bits_p_spl);
wxUint32 sample_fq, wxUint32 byte_p_sec, bool HandleOutputMSADPCM(wxDataInputStream& data, wxUint32 len,
wxUint16 byte_p_spl, wxUint16 bits_p_spl); wxUint16 channels, wxUint32 sample_fq,
wxUint32 byte_p_sec, wxUint16 byte_p_spl,
wxUint16 bits_p_spl);
bool HandleOutputG721(wxDataInputStream& data, wxUint32 len,
wxUint16 channels, wxUint32 sample_fq,
wxUint32 byte_p_sec, wxUint16 byte_p_spl,
wxUint16 bits_p_spl);
wxSoundFormatBase *HandleInputPCM(wxDataOutputStream& data); wxSoundFormatBase *HandleInputPCM(wxDataOutputStream& data);
wxSoundFormatBase *HandleInputG72X(wxDataOutputStream& data); wxSoundFormatBase *HandleInputG72X(wxDataOutputStream& data);

View File

@@ -41,6 +41,7 @@
#include "wx/mmedia/sndaiff.h" #include "wx/mmedia/sndaiff.h"
#include "wx/mmedia/sndpcm.h" #include "wx/mmedia/sndpcm.h"
#include "wx/mmedia/sndulaw.h" #include "wx/mmedia/sndulaw.h"
#include "wx/mmedia/sndmsad.h"
#ifdef __UNIX__ #ifdef __UNIX__
#include "wx/mmedia/sndoss.h" #include "wx/mmedia/sndoss.h"
@@ -310,6 +311,16 @@ wxString MMBoardSoundFile::GetStringInformation()
break; break;
} }
case wxSOUND_MSADPCM: {
wxSoundFormatMSAdpcm *adpcm_format = (wxSoundFormatMSAdpcm *)format;
info += wxString::Format(wxT("Microsoft ADPCM\n"));
info += wxString::Format(wxT("Sampling Rate: %d\n")
wxT("Number of channels: %d\n"),
adpcm_format->GetSampleRate(),
adpcm_format->GetChannels());
break;
}
case wxSOUND_ULAW: { case wxSOUND_ULAW: {
wxSoundFormatUlaw *ulaw_format = (wxSoundFormatUlaw *)format; wxSoundFormatUlaw *ulaw_format = (wxSoundFormatUlaw *)format;
info += wxT("ULAW\n"); info += wxT("ULAW\n");

View File

@@ -207,12 +207,20 @@ wxUint8 MMBoardApp::TestMultimediaCaps()
delete dev; delete dev;
// We test the OSS (Open Sound System) support. // We test the OSS (Open Sound System) support.
// WARNING: There is a conflict between ESD and ALSA // WARNING: There is a conflict between ESD and ALSA. We may be interrested
// in disabling the auto detection of OSS is ESD has been detected.
#if 1
if (!(caps & MM_SOUND_ESD)) {
#endif
dev = new wxSoundStreamOSS(); dev = new wxSoundStreamOSS();
if (dev->GetError() == wxSOUND_NOERROR) if (dev->GetError() == wxSOUND_NOERROR)
caps |= MM_SOUND_OSS; caps |= MM_SOUND_OSS;
delete dev; delete dev;
#if 1
}
#endif
#endif #endif
#ifdef __WIN32__ #ifdef __WIN32__

View File

@@ -19,7 +19,7 @@ OBJECTS=cdbase.o cdwin.o g711.o g721.o g723_24.o \
# any VPATH assignment not containing ':' # any VPATH assignment not containing ':'
VPATH = :$(top_srcdir)/src/mmedia # ':' for autoconf VPATH = :$(top_srcdir)/src/mmedia # ':' for autoconf
APPEXTRADEFS=-I$(top_srcdir)/include APPEXTRADEFS=-I$(top_srcdir)/include -I$(top_srcdir)/../include
include $(top_builddir)/src/makelib.env include $(top_builddir)/src/makelib.env

View File

@@ -10,6 +10,13 @@
#endif #endif
#include <wx/wxprec.h> #include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include "wx/defs.h"
#include "wx/string.h"
#include "wx/log.h"
#endif
#include "wx/mmedia/sndbase.h" #include "wx/mmedia/sndbase.h"
@@ -27,6 +34,8 @@ wxSoundFormatBase::~wxSoundFormatBase()
wxSoundFormatBase *wxSoundFormatBase::Clone() const wxSoundFormatBase *wxSoundFormatBase::Clone() const
{ {
wxLogFatalError(wxT("In wxSoundFormatBase::Clone() but I should"
" not be there"));
return NULL; return NULL;
} }

View File

@@ -379,11 +379,15 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format)
// We try to minimize the need of dynamic memory allocation by preallocating a buffer. But // We try to minimize the need of dynamic memory allocation by preallocating a buffer. But
// to be sure it will be efficient we minimize the best size. // to be sure it will be efficient we minimize the best size.
if (m_multiplier_in < m_multiplier_out) { if (m_multiplier_in < m_multiplier_out) {
m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_out); m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() *
m_best_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_in); m_multiplier_out);
m_best_size = (wxUint32)(m_sndio->GetBestSize() *
m_multiplier_in);
} else { } else {
m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_in); m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() *
m_best_size = (wxUint32)(m_sndio->GetBestSize() * m_multiplier_out); m_multiplier_in);
m_best_size = (wxUint32)(m_sndio->GetBestSize() *
m_multiplier_out);
} }
m_prebuffer = new char[m_prebuffer_size]; m_prebuffer = new char[m_prebuffer_size];

View File

@@ -18,6 +18,7 @@
#include "wx/mmedia/sndcpcm.h" #include "wx/mmedia/sndcpcm.h"
#include "wx/mmedia/sndulaw.h" #include "wx/mmedia/sndulaw.h"
#include "wx/mmedia/sndg72x.h" #include "wx/mmedia/sndg72x.h"
#include "wx/mmedia/sndmsad.h"
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Sound codec router // Sound codec router
@@ -106,6 +107,10 @@ bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format)
m_router = new wxSoundStreamG72X(*m_sndio); m_router = new wxSoundStreamG72X(*m_sndio);
m_router->SetSoundFormat(format); m_router->SetSoundFormat(format);
break; break;
case wxSOUND_MSADPCM:
m_router = new wxSoundStreamMSAdpcm(*m_sndio);
m_router->SetSoundFormat(format);
break;
default: default:
return FALSE; return FALSE;

View File

@@ -6,10 +6,17 @@
// CVSID: $Id$ // CVSID: $Id$
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
#ifdef __GNUG__ #ifdef __GNUG__
#pragma implementation "sndulaw.cpp" #pragma implementation "sndmsad.cpp"
#endif #endif
#include <wx/wxprec.h> #include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include "wx/defs.h"
#include "wx/memory.h"
#include "wx/log.h"
#endif
#include "wx/mmedia/sndbase.h" #include "wx/mmedia/sndbase.h"
#include "wx/mmedia/sndfile.h" #include "wx/mmedia/sndfile.h"
#include "wx/mmedia/sndpcm.h" #include "wx/mmedia/sndpcm.h"
@@ -22,12 +29,21 @@
wxSoundFormatMSAdpcm::wxSoundFormatMSAdpcm() wxSoundFormatMSAdpcm::wxSoundFormatMSAdpcm()
: m_srate(22050) : m_srate(22050)
{ {
m_coefs = new wxMSAdpcmCoefs(); m_ncoefs = 0;
m_coefs_len = 0;
m_coefs = NULL;
} }
wxSoundFormatMSAdpcm::~wxSoundFormatMSAdpcm() wxSoundFormatMSAdpcm::~wxSoundFormatMSAdpcm()
{ {
delete m_coefs; if (m_ncoefs) {
wxUint16 i;
for (i=0;i<m_ncoefs;i++)
delete[] m_coefs[i];
delete[] m_coefs;
}
} }
void wxSoundFormatMSAdpcm::SetSampleRate(wxUint32 srate) void wxSoundFormatMSAdpcm::SetSampleRate(wxUint32 srate)
@@ -40,34 +56,83 @@ wxUint32 wxSoundFormatMSAdpcm::GetSampleRate() const
return m_srate; return m_srate;
} }
void wxSoundFormatMSAdpcm::SetChannels(wxUint16 nchannels)
{
m_nchannels = nchannels;
}
wxUint16 wxSoundFormatMSAdpcm::GetChannels() const
{
return m_nchannels;
}
void wxSoundFormatMSAdpcm::SetCoefs(wxInt16 **coefs, wxUint16 ncoefs,
wxUint16 coefs_len)
{
wxUint16 i;
if (m_ncoefs) {
for (i=0;i<m_ncoefs;i++)
delete[] (m_coefs[i]);
delete[] m_coefs;
}
// TODO: Add some memory checking here
m_coefs = new (wxInt16 *)[ncoefs];
for (i=0;i<ncoefs;i++)
m_coefs[i] = new wxInt16[coefs_len];
m_ncoefs = ncoefs;
m_coefs_len = coefs_len;
}
void wxSoundFormatMSAdpcm::GetCoefs(wxInt16 **& coefs, wxUint16& ncoefs,
wxUint16& coefs_len) const
{
coefs = m_coefs;
ncoefs = m_ncoefs;
coefs_len = m_coefs_len;
}
void wxSoundFormatMSAdpcm::SetBlockSize(wxUint16 block_size)
{
m_block_size = block_size;
}
wxUint16 wxSoundFormatMSAdpcm::GetBlockSize() const
{
return m_block_size;
}
wxSoundFormatBase *wxSoundFormatMSAdpcm::Clone() const wxSoundFormatBase *wxSoundFormatMSAdpcm::Clone() const
{ {
wxSoundFormatMSAdpcm *adpcm = new wxSoundFormatMSAdpcm(); wxSoundFormatMSAdpcm *adpcm = new wxSoundFormatMSAdpcm();
adpcm->m_srate = m_srate; adpcm->m_srate = m_srate;
adpcm->m_coefs = new wxMSAdpcmCoefs(); adpcm->SetCoefs(m_coefs, m_ncoefs, m_coefs_len);
*(adpcm->m_coefs) = *m_coefs; adpcm->m_nchannels = m_nchannels;
adpcm->m_block_size = m_block_size;
return adpcm; return adpcm;
} }
wxUint32 wxSoundFormatMSAdpcm::GetTimeFromBytes(wxUint32 bytes) const wxUint32 wxSoundFormatMSAdpcm::GetTimeFromBytes(wxUint32 bytes) const
{ {
return 0; return 2 * bytes / (m_nchannels * m_srate);
} }
wxUint32 wxSoundFormatMSAdpcm::GetBytesFromTime(wxUint32 time) const wxUint32 wxSoundFormatMSAdpcm::GetBytesFromTime(wxUint32 time) const
{ {
return 0; return time * m_nchannels * m_srate / 2;
} }
bool wxSoundFormatMSAdpcm::operator !=(const wxSoundFormatBase& frmt2) const bool wxSoundFormatMSAdpcm::operator !=(const wxSoundFormatBase& frmt2) const
{ {
wxSoundFormatUlaw *adpcm = (wxSoundFormatMSAdpcm *)&frmt2; const wxSoundFormatMSAdpcm *adpcm = (const wxSoundFormatMSAdpcm *)&frmt2;
if (frmt2.GetType() != wxSOUND_MSADPCM) if (frmt2.GetType() != wxSOUND_MSADPCM)
return TRUE; return TRUE;
return (adpcm->m_srate != m_srate) && 0; return (adpcm->m_srate != m_srate) && (adpcm->m_nchannels != m_nchannels);
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@@ -79,6 +144,7 @@ wxSoundStreamMSAdpcm::wxSoundStreamMSAdpcm(wxSoundStream& sndio)
// PCM converter // PCM converter
m_router = new wxSoundRouterStream(sndio); m_router = new wxSoundRouterStream(sndio);
m_got_header = FALSE; m_got_header = FALSE;
m_stereo = FALSE;
} }
wxSoundStreamMSAdpcm::~wxSoundStreamMSAdpcm() wxSoundStreamMSAdpcm::~wxSoundStreamMSAdpcm()
@@ -94,44 +160,187 @@ wxSoundStream& wxSoundStreamMSAdpcm::Read(void *buffer, wxUint32 len)
} }
static wxInt16 gl_ADPCMcoeff_delta[] = { static wxInt16 gl_ADPCMcoeff_delta[] = {
230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307, 230, 230, 230 230, 230, 230, 230, 307, 409, 512, 614, 768, 614, 512, 409, 307,
230, 230, 230
}; };
static wxInt16 gl_ADPCMcoeff_1[] = { wxUint32 wxSoundStreamMSAdpcm::DecodeMonoADPCM(const void *in_buffer,
256, 512, 0, 192, 240, 460, 392 void *out_buffer,
}; wxUint32 in_len)
{
wxUint8 *ADPCMdata;
wxInt16 *PCMdata;
AdpcmState *state;
wxUint32 out_len;
static wxInt16 gl_ADPCMcoeff_2[] = { ADPCMdata = (wxUint8 *)in_buffer;
0, -256, 0, 64, 0, -208, -232 PCMdata = (wxInt16 *)out_buffer;
}; state = &m_state[0];
#define GET_DATA_16(i) i = *ADPCMdata++, i |= ((wxUint32)(*ADPCMdata++) << 8)
#define GET_DATA_8(i) i = (*ADPCMdata++)
out_len = 0;
while (in_len != 0) {
if (m_next_block == 0) {
GET_DATA_8(state->predictor);
GET_DATA_16(state->iDelta);
GET_DATA_16(state->samp1);
GET_DATA_16(state->samp2);
state->coeff[0] = state->coeff[1] = m_coefs[0][ state->predictor ];
*PCMdata++ = state->samp2;
*PCMdata++ = state->samp1;
in_len -= 7;
out_len += 4;
m_next_block = m_block_size;
continue;
}
while (in_len != 0 && m_next_block != 0) {
wxUint8 nib[2];
GET_DATA_8(nib[0]);
nib[1] = (nib[0] >> 4) & 0x0f;
nib[0] &= 0x0f;
Nibble(nib[0], state, &PCMdata);
Nibble(nib[1], state, &PCMdata);
in_len -= 4;
out_len += 4;
m_next_block -= 4;
}
}
return out_len;
#undef GET_DATA_16
#undef GET_DATA_8
}
wxUint32 wxSoundStreamMSAdpcm::DecodeStereoADPCM(const void *in_buffer,
void *out_buffer,
wxUint32 in_len)
{
wxUint8 *ADPCMdata;
wxInt16 *PCMdata;
AdpcmState *state0, *state1;
wxUint32 out_len;
ADPCMdata = (wxUint8 *)in_buffer;
PCMdata = (wxInt16 *)out_buffer;
state0 = &m_state[0];
state1 = &m_state[1];
#define GET_DATA_16(i) i = *ADPCMdata++, i |= ((wxUint32)(*ADPCMdata++) << 8)
#define GET_DATA_8(i) i = (*ADPCMdata++)
out_len = 0;
while (in_len != 0) {
if (!m_next_block) {
GET_DATA_8(state0->predictor);
GET_DATA_8(state1->predictor);
GET_DATA_16(state0->iDelta);
GET_DATA_16(state1->iDelta);
GET_DATA_16(state0->samp1);
GET_DATA_16(state1->samp1);
GET_DATA_16(state0->samp2);
GET_DATA_16(state1->samp2);
*PCMdata++ = state0->samp2;
*PCMdata++ = state1->samp2;
*PCMdata++ = state0->samp1;
*PCMdata++ = state1->samp1;
in_len -= 14;
out_len += 8;
m_next_block = m_block_size;
continue;
}
while (in_len != 0 && m_next_block > 0) {
wxUint8 nib[2];
GET_DATA_8(nib[0]);
nib[1] = (nib[0] >> 4) & 0x0f;
nib[0] &= 0x0f;
Nibble(nib[0], state0, &PCMdata);
Nibble(nib[1], state1, &PCMdata);
in_len -= 4;
out_len += 4;
m_next_block -= 4;
}
}
return out_len;
#undef GET_DATA_16
#undef GET_DATA_8
}
void wxSoundStreamMSAdpcm::Nibble(wxInt8 nyb,
AdpcmState *state,
wxInt16 **out_buffer)
{
wxUint32 new_delta;
wxInt32 new_sample;
// First: compute the next delta value
new_delta = (state->iDelta * gl_ADPCMcoeff_delta[nyb]) >> 8;
// If null, minor it by 16
if (!new_delta)
new_delta = 16;
// Barycentre
new_sample = (state->samp1 * state->coeff[0] +
state->samp2 * state->coeff[1]) / 256;
// Regenerate the sign
if (nyb & 0x08)
nyb -= 0x10;
new_sample += state->iDelta * nyb;
// Samples must be in [-32767, 32768]
if (new_sample < -32768)
new_sample = -32768;
else if (new_sample > 32767)
new_sample = 32767;
state->iDelta = new_delta;
state->samp2 = state->samp1;
state->samp1 = new_sample;
*(*out_buffer)++ = new_sample;
}
wxSoundStream& wxSoundStreamMSAdpcm::Write(const void *buffer, wxUint32 len) wxSoundStream& wxSoundStreamMSAdpcm::Write(const void *buffer, wxUint32 len)
{ {
wxInt16 delta; wxUint8 *out_buf;
wxUint8 ADPCMdata; wxUint32 new_len;
wxUint16 *PCMdata;
wxInt16 coeff1, coeff2;
#define GET_DATA_16 (*ADPCMdata++ | ((wxUint32)(*ADPCMdata++) << 8); // TODO: prealloc the output buffer
#define GET_DATA_8 (*ADPCMdata++) out_buf = new wxUint8[len*2];
if (!m_got_header) { if (!m_stereo)
i_predict = GET_DATA_8; new_len = DecodeMonoADPCM(buffer, out_buf, len);
delta = GET_DATA_16; else
samp1 = GET_DATA_16; new_len = DecodeStereoADPCM(buffer, out_buf, len);
PCMdata = GET_DATA_16;
len -= 3*2 + 1;
m_got_header = TRUE;
coeff1 = gl_ADPCMcoeff_1[i_predict]; m_router->Write(out_buf, new_len);
coeff2 = gl_ADPCMcoeff_2[i_predict];
}
while (len > 0) { m_lastcount = len;
nyb1 = GET_DATA_8; m_snderror = wxSOUND_NOERROR;
nyb0 = (nyb1 & 0xf0) >> 4;
nyb1 &= 0x0f;
delete[] out_buf;
return *this; return *this;
} }
@@ -143,17 +352,26 @@ wxUint32 wxSoundStreamMSAdpcm::GetBestSize() const
bool wxSoundStreamMSAdpcm::SetSoundFormat(const wxSoundFormatBase& format) bool wxSoundStreamMSAdpcm::SetSoundFormat(const wxSoundFormatBase& format)
{ {
if (format.GetType() != wxSOUND_ULAW) { if (format.GetType() != wxSOUND_MSADPCM) {
m_snderror = wxSOUND_INVFRMT; m_snderror = wxSOUND_INVFRMT;
return FALSE; return FALSE;
} }
wxSoundFormatPcm pcm; wxSoundFormatPcm pcm;
wxSoundFormatUlaw *ulaw; wxSoundFormatMSAdpcm *adpcm;
wxUint16 ncoefs, coefs_len;
wxSoundStreamCodec::SetSoundFormat(format); wxSoundStreamCodec::SetSoundFormat(format);
ulaw = (wxSoundFormatMSAdpcm *)m_sndformat; adpcm = (wxSoundFormatMSAdpcm *)m_sndformat;
adpcm->GetCoefs(m_coefs, ncoefs, coefs_len);
if (!ncoefs) {
wxLogError(__FILE__ ":%d: Number of ADPCM coefficients"
" must be non null", __LINE__);
return FALSE;
}
pcm.SetSampleRate(adpcm->GetSampleRate()); pcm.SetSampleRate(adpcm->GetSampleRate());
pcm.SetBPS(16); pcm.SetBPS(16);
@@ -161,6 +379,10 @@ bool wxSoundStreamMSAdpcm::SetSoundFormat(const wxSoundFormatBase& format)
pcm.Signed(TRUE); pcm.Signed(TRUE);
pcm.SetOrder(wxBYTE_ORDER); pcm.SetOrder(wxBYTE_ORDER);
m_stereo = (adpcm->GetChannels() == 2);
m_block_size = adpcm->GetBlockSize();
m_next_block = 0;
m_router->SetSoundFormat(pcm); m_router->SetSoundFormat(pcm);
return TRUE; return TRUE;

View File

@@ -163,8 +163,9 @@ bool wxSoundStreamUlaw::SetSoundFormat(const wxSoundFormatBase& format)
return FALSE; return FALSE;
} }
// As the codec only support 16 bits, Mono we must use a wxSoundRouter to filter the data and // As the codec only support 16 bits, Mono we must use a wxSoundRouter
// to translate them to a format supported by the sound card. // to filter the data and to translate them to a format supported
// by the sound card.
wxSoundFormatPcm pcm; wxSoundFormatPcm pcm;
wxSoundFormatUlaw *ulaw; wxSoundFormatUlaw *ulaw;

View File

@@ -29,6 +29,7 @@
#include "wx/mmedia/sndfile.h" #include "wx/mmedia/sndfile.h"
#include "wx/mmedia/sndpcm.h" #include "wx/mmedia/sndpcm.h"
#include "wx/mmedia/sndg72x.h" #include "wx/mmedia/sndg72x.h"
#include "wx/mmedia/sndmsad.h"
#include "wx/mmedia/sndwav.h" #include "wx/mmedia/sndwav.h"
#define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24)) #define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24))
@@ -97,7 +98,8 @@ bool wxSoundWave::CanRead()
return TRUE; return TRUE;
} }
bool wxSoundWave::HandleOutputPCM(wxDataInputStream& data, wxUint16 channels, bool wxSoundWave::HandleOutputPCM(wxDataInputStream& data, wxUint32 len,
wxUint16 channels,
wxUint32 sample_fq, wxUint32 byte_p_sec, wxUint32 sample_fq, wxUint32 byte_p_sec,
wxUint16 byte_p_spl, wxUint16 bits_p_spl) wxUint16 byte_p_spl, wxUint16 bits_p_spl)
{ {
@@ -112,10 +114,53 @@ bool wxSoundWave::HandleOutputPCM(wxDataInputStream& data, wxUint16 channels,
if (!SetSoundFormat(sndformat)) if (!SetSoundFormat(sndformat))
return FALSE; return FALSE;
m_input->SeekI(len, wxFromCurrent);
return TRUE; return TRUE;
} }
bool wxSoundWave::HandleOutputG721(wxDataInputStream& data, wxUint16 channels, bool wxSoundWave::HandleOutputMSADPCM(wxDataInputStream& data, wxUint32 len,
wxUint16 channels,
wxUint32 sample_fq, wxUint32 byte_p_sec,
wxUint16 byte_p_spl, wxUint16 bits_p_spl)
{
wxSoundFormatMSAdpcm sndformat;
wxInt16 *coefs[2];
wxUint16 coefs_len, i;
wxUint16 block_size;
sndformat.SetSampleRate(sample_fq);
sndformat.SetChannels(channels);
block_size = data.Read16();
coefs_len = data.Read16();
coefs[0] = new wxInt16[coefs_len];
coefs[1] = new wxInt16[coefs_len];
for (i=0;i<coefs_len;i++) {
coefs[0][i] = data.Read16();
coefs[1][i] = data.Read16();
}
sndformat.SetCoefs(coefs, 2, coefs_len);
sndformat.SetBlockSize(block_size);
delete[] coefs[0];
delete[] coefs[1];
if (!SetSoundFormat(sndformat))
return FALSE;
len -= coefs_len*4 + 4;
m_input->SeekI(len, wxFromCurrent);
return TRUE;
}
bool wxSoundWave::HandleOutputG721(wxDataInputStream& data, wxUint32 len,
wxUint16 channels,
wxUint32 sample_fq, wxUint32 byte_p_sec, wxUint32 sample_fq, wxUint32 byte_p_sec,
wxUint16 byte_p_spl, wxUint16 bits_p_spl) wxUint16 byte_p_spl, wxUint16 bits_p_spl)
{ {
@@ -127,6 +172,8 @@ bool wxSoundWave::HandleOutputG721(wxDataInputStream& data, wxUint16 channels,
if (!SetSoundFormat(sndformat)) if (!SetSoundFormat(sndformat))
return FALSE; return FALSE;
m_input->SeekI(len, wxFromCurrent);
return TRUE; return TRUE;
} }
@@ -173,16 +220,27 @@ bool wxSoundWave::PrepareToPlay()
// Get the common parameters // Get the common parameters
data >> format >> channels >> sample_fq data >> format >> channels >> sample_fq
>> byte_p_sec >> byte_p_spl >> bits_p_spl; >> byte_p_sec >> byte_p_spl >> bits_p_spl;
len -= 16;
switch (format) { switch (format) {
case 0x01: // PCM case 0x01: // PCM
if (!HandleOutputPCM(data, channels, sample_fq, if (!HandleOutputPCM(data, len, channels, sample_fq,
byte_p_sec, byte_p_spl, bits_p_spl)) byte_p_sec, byte_p_spl,
bits_p_spl))
return FALSE;
break;
case 0x02: // MS ADPCM
if (!HandleOutputMSADPCM(data, len,
channels, sample_fq,
byte_p_sec, byte_p_spl,
bits_p_spl))
return FALSE; return FALSE;
break; break;
case 0x40: // G721 case 0x40: // G721
if (!HandleOutputG721(data, channels, sample_fq, if (!HandleOutputG721(data, len,
byte_p_sec, byte_p_spl, bits_p_spl)) channels, sample_fq,
byte_p_sec, byte_p_spl,
bits_p_spl))
return FALSE; return FALSE;
break; break;
default: default:

View File

@@ -503,7 +503,8 @@ bool wxVideoXANIM::RestartXANIM()
m_video_output->SetSize(vibrato_size); m_video_output->SetSize(vibrato_size);
vibrato_size.SetWidth(vibrato_size.GetWidth()-1); vibrato_size.SetWidth(vibrato_size.GetWidth()-1);
m_video_output->SetSize(vibrato_size); m_video_output->SetSize(vibrato_size);
// Very useful ! Actually it sends a SETSIZE event to XAnim // Very useful ! Actually it "should" sends a SETSIZE event to XAnim
// FIXME: This event is not sent !!
m_paused = FALSE; m_paused = FALSE;

View File

@@ -17,6 +17,6 @@ OBJECTS=basic.o bmpshape.o composit.o divided.o lines.o misc.o \
# any VPATH assignment not containing ':' # any VPATH assignment not containing ':'
VPATH = :$(top_srcdir)/src/ogl # ':' for autoconf VPATH = :$(top_srcdir)/src/ogl # ':' for autoconf
APPEXTRADEFS=-I$(top_srcdir)/include APPEXTRADEFS=-I$(top_srcdir)/include -I$(top_srcdir)/../include
include $(top_builddir)/src/makelib.env include $(top_builddir)/src/makelib.env

View File

@@ -35,6 +35,6 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
Style.o \ Style.o \
ViewStyle.o ViewStyle.o
APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/include APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/include -I$(top_srcdir)/../include
include $(top_builddir)/src/makelib.env include $(top_builddir)/src/makelib.env

View File

@@ -35,6 +35,6 @@ OBJECTS=PlatWX.o ScintillaWX.o stc.o \
Style.o \ Style.o \
ViewStyle.o ViewStyle.o
APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/include APPEXTRADEFS=-D__WX__ -DSCI_LEXER -I$(scintilla_dir)/src -I$(scintilla_dir)/include -I$(top_srcdir)/include -I$(top_srcdir)/../include
include $(top_builddir)/src/makelib.env include $(top_builddir)/src/makelib.env