From 0662cd3286d6da0be81ef063633fec13c5cf741b Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Fri, 27 Aug 1999 17:40:40 +0000 Subject: [PATCH] Implemented Read in the PCM converter 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 --- utils/wxMMedia2/lib/Makefile.in | 2 +- utils/wxMMedia2/lib/converter.def | 6 +- utils/wxMMedia2/lib/sndaiff.cpp | 4 +- utils/wxMMedia2/lib/sndaiff.h | 4 +- utils/wxMMedia2/lib/sndbase.h | 8 +- utils/wxMMedia2/lib/sndcpcm.cpp | 67 ++++++-- utils/wxMMedia2/lib/sndcpcm.h | 6 +- utils/wxMMedia2/lib/sndesd.cpp | 8 +- utils/wxMMedia2/lib/sndesd.h | 4 +- utils/wxMMedia2/lib/sndfile.cpp | 15 +- utils/wxMMedia2/lib/sndfile.h | 12 +- utils/wxMMedia2/lib/sndg72x.cpp | 268 ++++++++++++++++++++++++++++++ utils/wxMMedia2/lib/sndg72x.h | 81 +++++++++ utils/wxMMedia2/lib/sndoss.cpp | 8 +- utils/wxMMedia2/lib/sndoss.h | 4 +- utils/wxMMedia2/lib/sndulaw.cpp | 6 +- utils/wxMMedia2/lib/sndulaw.h | 4 +- utils/wxMMedia2/lib/sndwav.cpp | 64 +++++-- utils/wxMMedia2/lib/sndwav.h | 13 +- utils/wxMMedia2/lib/sndwin.cpp | 8 +- utils/wxMMedia2/lib/sndwin.h | 4 +- 21 files changed, 515 insertions(+), 81 deletions(-) create mode 100644 utils/wxMMedia2/lib/sndg72x.cpp create mode 100644 utils/wxMMedia2/lib/sndg72x.h diff --git a/utils/wxMMedia2/lib/Makefile.in b/utils/wxMMedia2/lib/Makefile.in index 310d9b9628..fd733926d8 100644 --- a/utils/wxMMedia2/lib/Makefile.in +++ b/utils/wxMMedia2/lib/Makefile.in @@ -17,7 +17,7 @@ VPATH= $(top_srcdir)/utils/wxMMedia2/lib LIBTARGET=libwxmmedia2 OBJECTS=sndbase.o sndcodec.o sndpcm.o sndcpcm.o sndulaw.o sndfile.o sndoss.o\ - sndaiff.o sndwav.o \ + sndaiff.o sndwav.o sndg72x.o \ g711.o g721.o g723_24.o g723_40.o g72x.o \ cdbase.o cdunix.o \ vidbase.o vidxanm.o diff --git a/utils/wxMMedia2/lib/converter.def b/utils/wxMMedia2/lib/converter.def index dc8074b06e..b5279cc03f 100644 --- a/utils/wxMMedia2/lib/converter.def +++ b/utils/wxMMedia2/lib/converter.def @@ -1,5 +1,5 @@ #define DEFINE_CONV_8(name) \ -static void Convert_##name##_8(const char *buf_in, char *buf_out, size_t len) \ +static void Convert_##name##_8(const char *buf_in, char *buf_out, wxUint32 len) \ {\ wxUint16 val; \ \ @@ -10,7 +10,7 @@ static void Convert_##name##_8(const char *buf_in, char *buf_out, size_t len) \ #if SWAP_BYTES==0 #define DEFINE_CONV_16(name) \ -static void Convert_##name##_16_no(const char *buf_in, char *buf_out, size_t len) \ +static void Convert_##name##_16_no(const char *buf_in, char *buf_out, wxUint32 len) \ {\ wxUint16 val; \ \ @@ -22,7 +22,7 @@ static void Convert_##name##_16_no(const char *buf_in, char *buf_out, size_t len #else #define DEFINE_CONV_16(name) \ -static void Convert_##name##_16_yes(const char *buf_in, char *buf_out, size_t len) \ +static void Convert_##name##_16_yes(const char *buf_in, char *buf_out, wxUint32 len) \ {\ wxUint16 val; \ \ diff --git a/utils/wxMMedia2/lib/sndaiff.cpp b/utils/wxMMedia2/lib/sndaiff.cpp index 9ea8eb0af9..70a6a6a21c 100644 --- a/utils/wxMMedia2/lib/sndaiff.cpp +++ b/utils/wxMMedia2/lib/sndaiff.cpp @@ -126,12 +126,12 @@ bool wxSoundAiff::FinishRecording() return FALSE; } -size_t wxSoundAiff::GetData(void *buffer, size_t len) +wxUint32 wxSoundAiff::GetData(void *buffer, wxUint32 len) { return m_input->Read(buffer, len).LastRead(); } -size_t wxSoundAiff::PutData(const void *buffer, size_t len) +wxUint32 wxSoundAiff::PutData(const void *buffer, wxUint32 len) { return m_output->Write(buffer, len).LastWrite(); } diff --git a/utils/wxMMedia2/lib/sndaiff.h b/utils/wxMMedia2/lib/sndaiff.h index b2ab01ccb5..3f88a1a84e 100644 --- a/utils/wxMMedia2/lib/sndaiff.h +++ b/utils/wxMMedia2/lib/sndaiff.h @@ -32,8 +32,8 @@ class wxSoundAiff: public wxSoundFileStream { bool PrepareToRecord(unsigned long time); bool FinishRecording(); - size_t GetData(void *buffer, size_t len); - size_t PutData(const void *buffer, size_t len); + wxUint32 GetData(void *buffer, wxUint32 len); + wxUint32 PutData(const void *buffer, wxUint32 len); }; #endif diff --git a/utils/wxMMedia2/lib/sndbase.h b/utils/wxMMedia2/lib/sndbase.h index f7ecfc6fa5..50e57c7e80 100644 --- a/utils/wxMMedia2/lib/sndbase.h +++ b/utils/wxMMedia2/lib/sndbase.h @@ -71,9 +71,9 @@ class wxSoundStream { virtual ~wxSoundStream(); // Reads "len" bytes from the sound stream. - virtual wxSoundStream& Read(void *buffer, size_t len) = 0; + virtual wxSoundStream& Read(void *buffer, wxUint32 len) = 0; // Writes "len" byte to the sound stream. - virtual wxSoundStream& Write(const void *buffer, size_t len) = 0; + virtual wxSoundStream& Write(const void *buffer, wxUint32 len) = 0; // Returns the best size for IO calls virtual wxUint32 GetBestSize() const { return 1024; } @@ -97,7 +97,7 @@ class wxSoundStream { virtual void SetDuplexMode(bool duplex) = 0; wxSoundError GetError() const { return m_snderror; } - size_t GetLastAccess() const { return m_lastcount; } + wxUint32 GetLastAccess() const { return m_lastcount; } // This is only useful for device (I think). virtual bool QueueFilled() const { return TRUE; } @@ -110,7 +110,7 @@ class wxSoundStream { wxSoundError m_snderror; // Last access - size_t m_lastcount; + wxUint32 m_lastcount; // Event handler wxSoundStream *m_handler; diff --git a/utils/wxMMedia2/lib/sndcpcm.cpp b/utils/wxMMedia2/lib/sndcpcm.cpp index 8f54607ec1..e18908b231 100644 --- a/utils/wxMMedia2/lib/sndcpcm.cpp +++ b/utils/wxMMedia2/lib/sndcpcm.cpp @@ -34,16 +34,16 @@ wxSoundStreamPcm::~wxSoundStreamPcm() #include "converter.def" #undef SWAP_BYTES -wxSoundStreamPcm::ConverterType s_convert_16_to_8[] = { +wxSoundStreamPcm::ConverterType s_convert_out_16_to_8[] = { Convert_16to8_16_no, Convert_16to8_U2S_16_no, NULL, NULL, Convert_16to8_U2S_16_yes, - Convert_16to8_16_yes, + Convert_16to8_16_yes }; -wxSoundStreamPcm::ConverterType s_convert_16[] = { +wxSoundStreamPcm::ConverterType s_convert_out_16[] = { NULL, Convert_U2S_16_no, Convert_U2S_SWAP_16_no, @@ -52,7 +52,7 @@ wxSoundStreamPcm::ConverterType s_convert_16[] = { Convert_SWAP_16_no }; -wxSoundStreamPcm::ConverterType s_convert_8[] = { +wxSoundStreamPcm::ConverterType s_convert_out_8[] = { NULL, Convert_U2S_8, Convert_U2S_8, @@ -61,6 +61,19 @@ wxSoundStreamPcm::ConverterType s_convert_8[] = { NULL }; +wxSoundStreamPcm::ConverterType s_convert_in_8_to_16[] = { + Convert_8to16_8, + Convert_8to16_U2S_8, + Convert_8to16_U2S_SWAP_8, + NULL, + NULL, + Convert_8to16_SWAP_8 +}; + +wxSoundStreamPcm::ConverterType *s_convert_in_16 = s_convert_out_16; + +wxSoundStreamPcm::ConverterType *s_convert_in_8 = s_convert_out_8; + #define CONVERTER 0 #define CONVERTER_SIGN 1 #define CONVERTER_SIGN_SWAP 2 @@ -68,8 +81,11 @@ wxSoundStreamPcm::ConverterType s_convert_8[] = { #define CONVERTER_SWAP_SIGN 4 #define CONVERTER_SWAP 5 -wxSoundStream& wxSoundStreamPcm::Read(void *buffer, size_t len) +wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len) { + wxUint32 real_len; + char *tmp_buf; + if (!m_function_in) { m_sndio->Read(buffer, len); m_lastcount = m_sndio->GetLastAccess(); @@ -77,17 +93,30 @@ wxSoundStream& wxSoundStreamPcm::Read(void *buffer, size_t len) return *this; } - // TODO - m_sndio->Read(buffer, len); + real_len = (m_16_to_8) ? len / 2 : len; + + tmp_buf = new char[real_len]; + + m_sndio->Read(tmp_buf, real_len); m_lastcount = m_sndio->GetLastAccess(); m_snderror = m_sndio->GetError(); + if (m_snderror != wxSOUND_NOERR) + return *this; + + m_function_in(tmp_buf, (char *)buffer, m_lastcount); + + delete[] tmp_buf; + + if (m_16_to_8) + m_lastcount *= 2; + return *this; } -wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, size_t len) +wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, wxUint32 len) { char *tmp_buf; - size_t len2; + wxUint32 len2; if (!m_function_out) return m_sndio->Write(buffer, len); @@ -109,7 +138,7 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format) { wxSoundFormatBase *new_format; wxSoundFormatPcm *pcm_format, *pcm_format2; - ConverterType *current_table; + ConverterType *current_table_out, *current_table_in; int index; bool change_sign; @@ -132,11 +161,15 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format) m_16_to_8 = FALSE; if (pcm_format->GetBPS() == 16 && pcm_format2->GetBPS() == 8) { m_16_to_8 = TRUE; - current_table = s_convert_16_to_8; - } else if (pcm_format->GetBPS() == 16) - current_table = s_convert_16; - else - current_table = s_convert_8; + current_table_out = s_convert_out_16_to_8; + current_table_in = s_convert_in_8_to_16; + } else if (pcm_format->GetBPS() == 16) { + current_table_out = s_convert_out_16; + current_table_in = s_convert_in_16; + } else { + current_table_out = s_convert_out_8; + current_table_in = s_convert_in_8; + } change_sign = (pcm_format2->Signed() != pcm_format->Signed()); @@ -166,8 +199,8 @@ bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format) else index = CONVERTER; - m_function_out = current_table[index]; -// m_function_in = current_table[index+1]; + m_function_out = current_table_out[index]; + m_function_in = current_table_in[index]; m_sndio->SetSoundFormat(*new_format); m_sndformat = new_format; diff --git a/utils/wxMMedia2/lib/sndcpcm.h b/utils/wxMMedia2/lib/sndcpcm.h index e2a5db1fef..6880d8b7d0 100644 --- a/utils/wxMMedia2/lib/sndcpcm.h +++ b/utils/wxMMedia2/lib/sndcpcm.h @@ -21,13 +21,13 @@ class wxSoundStreamPcm: public wxSoundStreamCodec { public: - typedef void (*ConverterType)(const char *buf_in, char *buf_out, size_t len); + typedef void (*ConverterType)(const char *buf_in, char *buf_out, wxUint32 len); wxSoundStreamPcm(wxSoundStream& sndio); ~wxSoundStreamPcm(); - wxSoundStream& Read(void *buffer, size_t len); - wxSoundStream& Write(const void *buffer, size_t len); + wxSoundStream& Read(void *buffer, wxUint32 len); + wxSoundStream& Write(const void *buffer, wxUint32 len); bool SetSoundFormat(const wxSoundFormatBase& format); diff --git a/utils/wxMMedia2/lib/sndesd.cpp b/utils/wxMMedia2/lib/sndesd.cpp index 79cb1f10b3..85314f40c3 100644 --- a/utils/wxMMedia2/lib/sndesd.cpp +++ b/utils/wxMMedia2/lib/sndesd.cpp @@ -52,11 +52,11 @@ wxSoundStreamESD::~wxSoundStreamESD() esd_close(m_fd); } -wxSoundStream& wxSoundStreamESD::Read(void *buffer, size_t len) +wxSoundStream& wxSoundStreamESD::Read(void *buffer, wxUint32 len) { int ret; - m_lastcount = (size_t)ret = read(m_fd, buffer, len); + m_lastcount = (wxUint32)ret = read(m_fd, buffer, len); if (ret < 0) m_snderror = wxSOUND_IOERR; @@ -66,11 +66,11 @@ wxSoundStream& wxSoundStreamESD::Read(void *buffer, size_t len) return *this; } -wxSoundStream& wxSoundStreamESD::Write(const void *buffer, size_t len) +wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len) { int ret; - m_lastcount = (size_t)ret = write(m_fd, buffer, len); + m_lastcount = (wxUint32)ret = write(m_fd, buffer, len); if (ret < 0) m_snderror = wxSOUND_IOERR; diff --git a/utils/wxMMedia2/lib/sndesd.h b/utils/wxMMedia2/lib/sndesd.h index 56e44f88d2..19e8c95d5e 100644 --- a/utils/wxMMedia2/lib/sndesd.h +++ b/utils/wxMMedia2/lib/sndesd.h @@ -25,8 +25,8 @@ class wxSoundStreamESD : public wxSoundStream { wxSoundStreamESD(const wxString& hostname = _T("localhost")); ~wxSoundStreamESD(); - wxSoundStream& Read(void *buffer, size_t len); - wxSoundStream& Write(const void *buffer, size_t len); + wxSoundStream& Read(void *buffer, wxUint32 len); + wxSoundStream& Write(const void *buffer, wxUint32 len); bool SetSoundFormat(const wxSoundFormatBase& format); diff --git a/utils/wxMMedia2/lib/sndfile.cpp b/utils/wxMMedia2/lib/sndfile.cpp index e3dfd1e7c8..1234726300 100644 --- a/utils/wxMMedia2/lib/sndfile.cpp +++ b/utils/wxMMedia2/lib/sndfile.cpp @@ -16,6 +16,7 @@ #include "sndfile.h" #include "sndcpcm.h" #include "sndulaw.h" +#include "sndg72x.h" // -------------------------------------------------------------------------- // Sound codec router @@ -33,7 +34,7 @@ wxSoundRouterStream::~wxSoundRouterStream() delete m_router; } -wxSoundStream& wxSoundRouterStream::Read(void *buffer, size_t len) +wxSoundStream& wxSoundRouterStream::Read(void *buffer, wxUint32 len) { if (m_router) { m_router->Read(buffer, len); @@ -47,7 +48,7 @@ wxSoundStream& wxSoundRouterStream::Read(void *buffer, size_t len) return *this; } -wxSoundStream& wxSoundRouterStream::Write(const void *buffer, size_t len) +wxSoundStream& wxSoundRouterStream::Write(const void *buffer, wxUint32 len) { if (m_router) { m_router->Write(buffer, len); @@ -82,6 +83,10 @@ bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format) 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; @@ -230,13 +235,13 @@ bool wxSoundFileStream::Resume() 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; @@ -263,7 +268,7 @@ bool wxSoundFileStream::StopProduction() void wxSoundFileStream::OnSoundEvent(int evt) { - size_t len = m_sndio->GetBestSize(); + wxUint32 len = m_sndio->GetBestSize(); char *buffer; buffer = new char[len]; diff --git a/utils/wxMMedia2/lib/sndfile.h b/utils/wxMMedia2/lib/sndfile.h index f08a1db83a..d710a2f1a6 100644 --- a/utils/wxMMedia2/lib/sndfile.h +++ b/utils/wxMMedia2/lib/sndfile.h @@ -25,8 +25,8 @@ class WXDLLEXPORT wxSoundRouterStream: public wxSoundStreamCodec { wxSoundRouterStream(wxSoundStream& sndio); ~wxSoundRouterStream(); - wxSoundStream& Read(void *buffer, size_t len); - wxSoundStream& Write(const void *buffer, size_t len); + wxSoundStream& Read(void *buffer, wxUint32 len); + wxSoundStream& Write(const void *buffer, wxUint32 len); bool SetSoundFormat(const wxSoundFormatBase& format); @@ -67,8 +67,8 @@ class wxSoundFileStream: public wxSoundStream { unsigned long GetLength() const; - wxSoundStream& Read(void *buffer, size_t len); - wxSoundStream& Write(const void *buffer, size_t len); + wxSoundStream& Read(void *buffer, wxUint32 len); + wxSoundStream& Write(const void *buffer, wxUint32 len); void SetDuplexMode(bool duplex); @@ -90,8 +90,8 @@ class wxSoundFileStream: public wxSoundStream { virtual bool PrepareToRecord(unsigned long time) = 0; virtual bool FinishRecording() = 0; - virtual size_t GetData(void *buffer, size_t len) = 0; - virtual size_t PutData(const void *buffer, size_t len) = 0; + virtual wxUint32 GetData(void *buffer, wxUint32 len) = 0; + virtual wxUint32 PutData(const void *buffer, wxUint32 len) = 0; void OnSoundEvent(int evt); }; diff --git a/utils/wxMMedia2/lib/sndg72x.cpp b/utils/wxMMedia2/lib/sndg72x.cpp new file mode 100644 index 0000000000..a14fbd12e6 --- /dev/null +++ b/utils/wxMMedia2/lib/sndg72x.cpp @@ -0,0 +1,268 @@ +// -------------------------------------------------------------------------- +// Name: sndulaw.cpp +// Purpose: +// Date: 08/11/1999 +// Author: Guilhem Lavaux (C) 1999 +// CVSID: $Id$ +// -------------------------------------------------------------------------- +#ifdef __GNUG__ +#pragma implementation "sndulaw.cpp" +#endif + +#include +#include "sndbase.h" +#include "sndfile.h" +#include "sndpcm.h" +#include "sndulaw.h" +#include "sndg72x.h" +#include "g72x.h" + +// -------------------------------------------------------------------------- +// wxSoundFormatG72X +// -------------------------------------------------------------------------- + +wxSoundFormatG72X::wxSoundFormatG72X() + : m_srate(22050) +{ +} + +wxSoundFormatG72X::~wxSoundFormatG72X() +{ +} + +void wxSoundFormatG72X::SetSampleRate(wxUint32 srate) +{ + m_srate = srate; +} + +wxUint32 wxSoundFormatG72X::GetSampleRate() const +{ + return m_srate; +} + +void wxSoundFormatG72X::SetG72XType(wxSoundG72XType type) +{ + m_g72x_type = type; +} + +wxSoundFormatBase *wxSoundFormatG72X::Clone() const +{ + wxSoundFormatG72X *g72x = new wxSoundFormatG72X(); + + g72x->m_srate = m_srate; + g72x->m_g72x_type = m_g72x_type; + return g72x; +} + +wxUint32 wxSoundFormatG72X::GetTimeFromBytes(wxUint32 bytes) const +{ + int n_bits; + + switch (m_g72x_type) { + case wxSOUND_G721: + n_bits = 4; + break; + case wxSOUND_G723_24: + n_bits = 3; + break; + case wxSOUND_G723_40: + n_bits = 5; + break; + default: + n_bits = 0; + break; + } + return (wxUint32)((bytes / m_srate) * ((float)n_bits / 8)); +} + +wxUint32 wxSoundFormatG72X::GetBytesFromTime(wxUint32 time) const +{ + int n_bits; + + switch (m_g72x_type) { + case wxSOUND_G721: + n_bits = 4; + break; + case wxSOUND_G723_24: + n_bits = 3; + break; + case wxSOUND_G723_40: + n_bits = 5; + break; + default: + n_bits = 0; + } + return (wxUint32)(time * (m_srate * ((float)n_bits / 8))); +} + +bool wxSoundFormatG72X::operator !=(const wxSoundFormatBase& frmt2) const +{ + wxSoundFormatG72X *g72x = (wxSoundFormatG72X *)&frmt2; + + if (frmt2.GetType() != wxSOUND_G72X) + return TRUE; + + return (g72x->m_srate != m_srate || g72x->m_g72x_type != m_g72x_type); +} + +// -------------------------------------------------------------------------- +// wxSoundStreamG72X +// -------------------------------------------------------------------------- +wxSoundStreamG72X::wxSoundStreamG72X(wxSoundStream& sndio) + : wxSoundStreamCodec(sndio) +{ + // PCM converter + m_router = new wxSoundRouterStream(sndio); + m_state = new struct g72x_state; + g72x_init_state(m_state); +} + +wxSoundStreamG72X::~wxSoundStreamG72X() +{ + delete m_router; +} + +wxSoundStream& wxSoundStreamG72X::Read(void *buffer, wxUint32 len) +{ + return *this; +} + +wxSoundStream& wxSoundStreamG72X::Write(const void *buffer, wxUint32 len) +{ + wxUint16 *old_linear; + register wxUint16 *linear_buffer; + register wxUint32 countdown = len; + register wxUint32 real_len; + + real_len = (wxUint32)(len * ((float)m_n_bits / 8)); + + old_linear = linear_buffer = new wxUint16[real_len]; + + // Bad, we override the const + m_io_buffer = (wxUint8 *)buffer; + m_current_b_pos = 0; + + while (countdown != 0) { + *linear_buffer++ = m_decoder(GetBits(), AUDIO_ENCODING_LINEAR, m_state); + countdown--; + } + m_lastcount = len; + + m_router->Write(old_linear, real_len); + + delete[] old_linear; + + return *m_router; +} + +bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format) +{ + if (format.GetType() != wxSOUND_G72X) { + m_snderror = wxSOUND_INVFRMT; + return FALSE; + } + + wxSoundFormatPcm pcm; + wxSoundFormatG72X *g72x; + + wxSoundStreamCodec::SetSoundFormat(format); + + g72x = (wxSoundFormatG72X *)m_sndformat; + + pcm.SetSampleRate(g72x->GetSampleRate()); + pcm.SetBPS(16); + pcm.SetChannels(1); + pcm.Signed(TRUE); + pcm.SetOrder(wxBYTE_ORDER); + + switch (g72x->GetG72XType()) { + case wxSOUND_G721: + m_n_bits = 4; + m_coder = g721_encoder; + m_decoder = g721_decoder; + break; + case wxSOUND_G723_24: + m_n_bits = 3; + m_coder = g723_24_encoder; + m_decoder = g723_24_decoder; + break; + case wxSOUND_G723_40: + m_n_bits = 5; + m_coder = g723_40_encoder; + m_decoder = g723_40_decoder; + break; + } + + m_router->SetSoundFormat(pcm); + + return TRUE; +} + +#define BYTE_SIZE 8 + +wxUint8 wxSoundStreamG72X::GetBits() +{ + register wxUint8 bits; + + if (m_current_b_pos < m_n_bits) { + register wxUint8 b_left; + + // TRANSLATE the mask + m_current_mask >>= m_current_b_pos; + + // GET the last bits: 0001..1 + bits = (m_current_byte & m_current_mask) << (m_n_bits - m_current_b_pos); + + // GEN: 1. n times .1000 + b_left = BYTE_SIZE-m_n_bits; + m_current_mask = ((1 << m_n_bits) - 1) << b_left; + + // GET the next byte + m_current_byte = *m_io_buffer++; + + register wxUint8 tmp_mask; + + // COMPUTE a new temporary mask to get the last bits + b_left = m_n_bits - b_left; + tmp_mask = (1 << b_left) - 1; + // TRANSLATE the old mask to get ready for the next time + m_current_mask >>= b_left; + + // COMPUTE the new bit position + b_left = BYTE_SIZE - b_left; + m_current_b_pos = b_left; + tmp_mask <<= b_left; + + // GET the last bits + bits |= (m_current_byte & tmp_mask) >> b_left; + } else { + m_current_mask >>= m_n_bits; + m_current_b_pos -= m_n_bits; + bits = (m_current_byte & m_current_mask) >> m_current_b_pos; + } + return bits; +} + +void wxSoundStreamG72X::PutBits(wxUint8 bits) +{ + if (m_current_b_pos < m_n_bits) { + register wxUint8 tmp_mask; + register wxUint8 diff; + + diff = m_n_bits - m_current_b_pos; + // Pack bits and put the byte in the buffer + m_current_byte |= bits >> diff; + *m_io_buffer++ = m_current_byte; + + // Gen a mask + tmp_mask = ~((1 << diff) - 1); + + m_current_b_pos = BYTE_SIZE - (m_n_bits - m_current_b_pos); + + m_current_byte = (bits & (tmp_mask)) << m_current_b_pos; + } else { + m_current_b_pos -= m_n_bits; + bits <<= m_current_b_pos; + m_current_byte |= bits; + } +} diff --git a/utils/wxMMedia2/lib/sndg72x.h b/utils/wxMMedia2/lib/sndg72x.h new file mode 100644 index 0000000000..53d6b8bd5c --- /dev/null +++ b/utils/wxMMedia2/lib/sndg72x.h @@ -0,0 +1,81 @@ +// -------------------------------------------------------------------------- +// Name: sndg.h +// Purpose: +// Date: 08/11/1999 +// Author: Guilhem Lavaux (C) 1999 +// CVSID: $Id$ +// -------------------------------------------------------------------------- +#ifndef _WX_SNDG72X_H +#define _WX_SNDG72X_H + +#ifdef __GNUG__ +#pragma interface "sndg72x.h" +#endif + +#include +#include "sndcodec.h" +#include "sndbase.h" + +typedef enum { + wxSOUND_G721, + wxSOUND_G723_24, + wxSOUND_G723_40 +} wxSoundG72XType; + +// +// G72X format +// +class WXDLLEXPORT wxSoundFormatG72X: public wxSoundFormatBase { + public: + wxSoundFormatG72X(); + ~wxSoundFormatG72X(); + + void SetG72XType(wxSoundG72XType type); + wxSoundG72XType GetG72XType() const { return m_g72x_type; } + + void SetSampleRate(wxUint32 srate); + wxUint32 GetSampleRate() const; + + wxSoundFormatType GetType() const { return wxSOUND_G72X; } + wxSoundFormatBase *Clone() const; + + wxUint32 GetTimeFromBytes(wxUint32 bytes) const; + wxUint32 GetBytesFromTime(wxUint32 time) const; + + bool operator !=(const wxSoundFormatBase& frmt2) const; + + protected: + wxUint32 m_srate; + wxSoundG72XType m_g72x_type; +}; + +// +// ULAW converter class +// + +class WXDLLEXPORT wxSoundRouterStream; +class WXDLLEXPORT wxSoundStreamG72X: public wxSoundStreamCodec { + public: + wxSoundStreamG72X(wxSoundStream& sndio); + ~wxSoundStreamG72X(); + + wxSoundStream& Read(void *buffer, wxUint32 len); + wxSoundStream& Write(const void *buffer, wxUint32 len); + + bool SetSoundFormat(const wxSoundFormatBase& format); + + protected: + wxSoundRouterStream *m_router; + wxUint8 m_n_bits, m_current_mask, m_current_b_pos, m_current_byte; + wxUint8 *m_io_buffer; + struct g72x_state *m_state; + + int (*m_coder)(int code, int in_code, struct g72x_state *state); + int (*m_decoder)(int code, int out_code, struct g72x_state *state); + + protected: + void PutBits(wxUint8 bits); + wxUint8 GetBits(); +}; + +#endif diff --git a/utils/wxMMedia2/lib/sndoss.cpp b/utils/wxMMedia2/lib/sndoss.cpp index e794b20032..60fb82a2bd 100644 --- a/utils/wxMMedia2/lib/sndoss.cpp +++ b/utils/wxMMedia2/lib/sndoss.cpp @@ -60,11 +60,11 @@ wxUint32 wxSoundStreamOSS::GetBestSize() const return m_bufsize; } -wxSoundStream& wxSoundStreamOSS::Read(void *buffer, size_t len) +wxSoundStream& wxSoundStreamOSS::Read(void *buffer, wxUint32 len) { int ret; - m_lastcount = (size_t)ret = read(m_fd, buffer, len); + m_lastcount = (wxUint32)ret = read(m_fd, buffer, len); m_q_filled = TRUE; if (ret < 0) @@ -75,11 +75,11 @@ wxSoundStream& wxSoundStreamOSS::Read(void *buffer, size_t len) return *this; } -wxSoundStream& wxSoundStreamOSS::Write(const void *buffer, size_t len) +wxSoundStream& wxSoundStreamOSS::Write(const void *buffer, wxUint32 len) { int ret; - m_lastcount = (size_t)ret = write(m_fd, buffer, len); + m_lastcount = (wxUint32)ret = write(m_fd, buffer, len); m_q_filled = TRUE; if (ret < 0) diff --git a/utils/wxMMedia2/lib/sndoss.h b/utils/wxMMedia2/lib/sndoss.h index 84fc3f314e..4d0e79e08b 100644 --- a/utils/wxMMedia2/lib/sndoss.h +++ b/utils/wxMMedia2/lib/sndoss.h @@ -25,8 +25,8 @@ class wxSoundStreamOSS : public wxSoundStream { wxSoundStreamOSS(const wxString& dev_name = _T("/dev/dsp")); ~wxSoundStreamOSS(); - wxSoundStream& Read(void *buffer, size_t len); - wxSoundStream& Write(const void *buffer, size_t len); + wxSoundStream& Read(void *buffer, wxUint32 len); + wxSoundStream& Write(const void *buffer, wxUint32 len); wxUint32 GetBestSize() const; bool SetSoundFormat(const wxSoundFormatBase& format); diff --git a/utils/wxMMedia2/lib/sndulaw.cpp b/utils/wxMMedia2/lib/sndulaw.cpp index 3142d173c5..620abb7aa1 100644 --- a/utils/wxMMedia2/lib/sndulaw.cpp +++ b/utils/wxMMedia2/lib/sndulaw.cpp @@ -82,17 +82,17 @@ wxSoundStreamUlaw::~wxSoundStreamUlaw() delete m_router; } -wxSoundStream& wxSoundStreamUlaw::Read(void *buffer, size_t len) +wxSoundStream& wxSoundStreamUlaw::Read(void *buffer, wxUint32 len) { return *this; } -wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, size_t len) +wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, wxUint32 len) { wxUint16 *old_linear; register wxUint16 *linear_buffer; register const wxUint8 *ulaw_buffer; - register size_t countdown = len; + register wxUint32 countdown = len; old_linear = linear_buffer = new wxUint16[len*2]; ulaw_buffer = (const wxUint8 *)buffer; diff --git a/utils/wxMMedia2/lib/sndulaw.h b/utils/wxMMedia2/lib/sndulaw.h index ef893d2e85..67129da083 100644 --- a/utils/wxMMedia2/lib/sndulaw.h +++ b/utils/wxMMedia2/lib/sndulaw.h @@ -49,8 +49,8 @@ class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec { wxSoundStreamUlaw(wxSoundStream& sndio); ~wxSoundStreamUlaw(); - wxSoundStream& Read(void *buffer, size_t len); - wxSoundStream& Write(const void *buffer, size_t len); + wxSoundStream& Read(void *buffer, wxUint32 len); + wxSoundStream& Write(const void *buffer, wxUint32 len); bool SetSoundFormat(const wxSoundFormatBase& format); diff --git a/utils/wxMMedia2/lib/sndwav.cpp b/utils/wxMMedia2/lib/sndwav.cpp index f0d3f66a29..b4fa4faaa0 100644 --- a/utils/wxMMedia2/lib/sndwav.cpp +++ b/utils/wxMMedia2/lib/sndwav.cpp @@ -19,6 +19,7 @@ #include "sndcodec.h" #include "sndfile.h" #include "sndpcm.h" +#include "sndg72x.h" #include "sndwav.h" #define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24)) @@ -76,6 +77,39 @@ bool wxSoundWave::CanRead() return TRUE; } +bool wxSoundWave::HandlePCM(wxDataInputStream& data, wxUint16 channels, + wxUint32 sample_fq, wxUint32 byte_p_sec, + wxUint16 byte_p_spl, wxUint16 bits_p_spl) +{ + wxSoundFormatPcm sndformat; + + sndformat.SetSampleRate(sample_fq); + sndformat.SetBPS(bits_p_spl); + sndformat.SetChannels(channels); + sndformat.Signed(TRUE); + sndformat.SetOrder(wxLITTLE_ENDIAN); + + if (!SetSoundFormat(sndformat)) + return FALSE; + + return TRUE; +} + +bool wxSoundWave::HandleG721(wxDataInputStream& data, wxUint16 channels, + wxUint32 sample_fq, wxUint32 byte_p_sec, + wxUint16 byte_p_spl, wxUint16 bits_p_spl) +{ + wxSoundFormatG72X sndformat; + + sndformat.SetSampleRate(sample_fq); + sndformat.SetG72XType(wxSOUND_G721); + + if (!SetSoundFormat(sndformat)) + return FALSE; + + return TRUE; +} + bool wxSoundWave::PrepareToPlay() { wxUint32 signature, len; @@ -112,21 +146,25 @@ bool wxSoundWave::PrepareToPlay() case FMT_SIGNATURE: { // "fmt " wxUint16 format, channels, byte_p_spl, bits_p_spl; wxUint32 sample_fq, byte_p_sec; - wxSoundFormatPcm sndformat; data >> format >> channels >> sample_fq >> byte_p_sec >> byte_p_spl >> bits_p_spl; - FAIL_WITH(format != 1, wxSOUND_NOCODEC); - - sndformat.SetSampleRate(sample_fq); - sndformat.SetBPS(bits_p_spl); - sndformat.SetChannels(channels); - sndformat.Signed(TRUE); - sndformat.SetOrder(wxLITTLE_ENDIAN); - - if (!SetSoundFormat(sndformat)) + + switch (format) { + case 0x01: + if (!HandlePCM(data, channels, sample_fq, + byte_p_sec, byte_p_spl, bits_p_spl)) + return FALSE; + break; + case 0x40: + if (!HandleG721(data, channels, sample_fq, + byte_p_sec, byte_p_spl, bits_p_spl)) + return FALSE; + break; + default: + m_snderror = wxSOUND_NOCODEC; return FALSE; - m_input->SeekI(len-16, wxFromCurrent); + } break; } case DATA_SIGNATURE: // "data" @@ -212,12 +250,12 @@ bool wxSoundWave::FinishRecording() return TRUE; } -size_t wxSoundWave::GetData(void *buffer, size_t len) +wxUint32 wxSoundWave::GetData(void *buffer, wxUint32 len) { return m_input->Read(buffer, len).LastRead(); } -size_t wxSoundWave::PutData(const void *buffer, size_t len) +wxUint32 wxSoundWave::PutData(const void *buffer, wxUint32 len) { return m_output->Write(buffer, len).LastWrite(); } diff --git a/utils/wxMMedia2/lib/sndwav.h b/utils/wxMMedia2/lib/sndwav.h index 32b66737e0..295b4d86a7 100644 --- a/utils/wxMMedia2/lib/sndwav.h +++ b/utils/wxMMedia2/lib/sndwav.h @@ -12,7 +12,9 @@ #pragma interface "sndwav.h" #endif +#include #include +#include #include "sndbase.h" #include "sndcodec.h" #include "sndfile.h" @@ -34,8 +36,15 @@ class wxSoundWave: public wxSoundFileStream { bool PrepareToRecord(unsigned long time); bool FinishRecording(); - size_t GetData(void *buffer, size_t len); - size_t PutData(const void *buffer, size_t len); + wxUint32 GetData(void *buffer, wxUint32 len); + wxUint32 PutData(const void *buffer, wxUint32 len); + + bool HandlePCM(wxDataInputStream& data, wxUint16 channels, + wxUint32 sample_fq, wxUint32 byte_p_sec, + wxUint16 byte_p_spl, wxUint16 bits_p_spl); + bool HandleG721(wxDataInputStream& data, wxUint16 channels, + wxUint32 sample_fq, wxUint32 byte_p_sec, + wxUint16 byte_p_spl, wxUint16 bits_p_spl); }; #endif diff --git a/utils/wxMMedia2/lib/sndwin.cpp b/utils/wxMMedia2/lib/sndwin.cpp index 2b892094b6..b4527bd17f 100644 --- a/utils/wxMMedia2/lib/sndwin.cpp +++ b/utils/wxMMedia2/lib/sndwin.cpp @@ -379,7 +379,7 @@ wxSoundInfoHeader *wxSoundStreamWin::NextFragmentOutput() return m_headers_play[m_current_frag_out]; } -wxSoundStream& wxSoundStreamWin::Write(const void *buffer, size_t len) +wxSoundStream& wxSoundStreamWin::Write(const void *buffer, wxUint32 len) { m_lastcount = 0; if (!m_internal->m_output_enabled) @@ -387,7 +387,7 @@ wxSoundStream& wxSoundStreamWin::Write(const void *buffer, size_t len) while (len > 0) { wxSoundInfoHeader *header; - size_t to_copy; + wxUint32 to_copy; header = NextFragmentOutput(); @@ -423,10 +423,10 @@ wxSoundInfoHeader *wxSoundStreamWin::NextFragmentInput() return header; } -wxSoundStream& wxSoundStreamWin::Read(void *buffer, size_t len) +wxSoundStream& wxSoundStreamWin::Read(void *buffer, wxUint32 len) { wxSoundInfoHeader *header; - size_t to_copy; + wxUint32 to_copy; m_lastcount = 0; if (!m_internal->m_input_enabled) diff --git a/utils/wxMMedia2/lib/sndwin.h b/utils/wxMMedia2/lib/sndwin.h index 8d9a89bbde..549d533eaf 100644 --- a/utils/wxMMedia2/lib/sndwin.h +++ b/utils/wxMMedia2/lib/sndwin.h @@ -19,8 +19,8 @@ class WXDLLEXPORT wxSoundStreamWin : public wxSoundStream { wxSoundStreamWin(); ~wxSoundStreamWin(); - wxSoundStream& Write(const void *buffer, size_t len); - wxSoundStream& Read(void *buffer, size_t len); + wxSoundStream& Write(const void *buffer, wxUint32 len); + wxSoundStream& Read(void *buffer, wxUint32 len); bool SetSoundFormat(wxSoundFormatBase& base); void SetDuplexMode(bool on) {} -- 2.45.2