From 56dc1ffd50dac2369237e528abca6c12ea179c19 Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Sat, 6 Nov 1999 17:44:03 +0000 Subject: [PATCH] Fixed wxMemoryOutputStream (it wasn't working at all) Fixed wxStreamBuffer to support features of wxMemoryOutputStream wxMMedia2 updates (various fixes) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4406 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/mstream.cpp | 3 +- src/common/stream.cpp | 30 ++++++---- utils/wxMMedia2/README | 8 --- utils/wxMMedia2/lib/sndaiff.cpp | 38 +++++++++++++ utils/wxMMedia2/lib/sndaiff.h | 2 + utils/wxMMedia2/lib/sndbase.h | 3 - utils/wxMMedia2/lib/sndcodec.cpp | 5 ++ utils/wxMMedia2/lib/sndcodec.h | 1 + utils/wxMMedia2/lib/sndcpcm.cpp | 17 ++++++ utils/wxMMedia2/lib/sndesd.cpp | 15 +++-- utils/wxMMedia2/lib/sndesd.h | 3 + utils/wxMMedia2/lib/sndfile.cpp | 12 +++- utils/wxMMedia2/lib/sndfile.h | 4 +- utils/wxMMedia2/lib/sndg72x.cpp | 37 ++++++++++++- utils/wxMMedia2/lib/sndulaw.cpp | 5 ++ utils/wxMMedia2/lib/sndulaw.h | 2 + utils/wxMMedia2/lib/sndwav.cpp | 62 ++++++++++++--------- utils/wxMMedia2/lib/sndwin.cpp | 82 ++++++++++++++++++---------- utils/wxMMedia2/lib/sndwin.h | 2 +- utils/wxMMedia2/sample/test_med2.cpp | 13 ++++- 20 files changed, 257 insertions(+), 87 deletions(-) diff --git a/src/common/mstream.cpp b/src/common/mstream.cpp index 3e656ba3e8..aed7cae179 100644 --- a/src/common/mstream.cpp +++ b/src/common/mstream.cpp @@ -77,7 +77,8 @@ wxMemoryOutputStream::wxMemoryOutputStream(char *data, size_t len) m_o_streambuf = new wxStreamBuffer(wxStreamBuffer::write); if (data) m_o_streambuf->SetBufferIO(data, data+len); - m_o_streambuf->Fixed(TRUE); + m_o_streambuf->Fixed(FALSE); + m_o_streambuf->Flushable(FALSE); } wxMemoryOutputStream::~wxMemoryOutputStream() diff --git a/src/common/stream.cpp b/src/common/stream.cpp index 31760bb582..ed5190b1dc 100644 --- a/src/common/stream.cpp +++ b/src/common/stream.cpp @@ -165,10 +165,17 @@ void wxStreamBuffer::PutToBuffer(const void *buffer, size_t size) size_t s_toput = m_buffer_end-m_buffer_pos; if (s_toput < size && !m_fixed) { - m_buffer_start = (char *)realloc(m_buffer_start, m_buffer_size+size); - // I round a bit - m_buffer_size += size; - m_buffer_end = m_buffer_start+m_buffer_size; + if (!m_buffer_start) + SetBufferIO(size); + else { + size_t delta = m_buffer_pos-m_buffer_start; + + m_buffer_start = (char *)realloc(m_buffer_start, m_buffer_size+size); + m_buffer_pos = m_buffer_start + delta; + // I round a bit + m_buffer_size += size; + m_buffer_end = m_buffer_start+m_buffer_size; + } s_toput = size; } if (s_toput > size) @@ -306,7 +313,7 @@ size_t wxStreamBuffer::Write(const void *buffer, size_t size) // ------------------ m_stream->m_lasterror = wxStream_NOERROR; - if (!m_buffer_size) + if (!m_buffer_size && m_fixed) return (m_stream->m_lastcount = m_stream->OnSysWrite(buffer, size)); // ------------------ @@ -320,7 +327,9 @@ size_t wxStreamBuffer::Write(const void *buffer, size_t size) // First case: the buffer to write is larger than the stream buffer, // we split it - if (size > buf_left) { + // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream), + // we always go to the second case. + if (size > buf_left && m_fixed) { PutToBuffer(buffer, buf_left); size -= buf_left; buffer = (char *)buffer + buf_left; // ANSI C++ violation. @@ -493,7 +502,6 @@ char *wxInputStream::AllocSpaceWBack(size_t needed_size) if (!temp_b) return NULL; m_wback = temp_b; - m_wbackcur += needed_size; memmove(m_wback+needed_size, m_wback, old_size); @@ -502,7 +510,7 @@ char *wxInputStream::AllocSpaceWBack(size_t needed_size) size_t wxInputStream::GetWBack(char *buf, size_t bsize) { - size_t s_toget = m_wbackcur; + size_t s_toget = m_wbacksize-m_wbackcur; if (!m_wback) return 0; @@ -510,10 +518,10 @@ size_t wxInputStream::GetWBack(char *buf, size_t bsize) if (bsize < s_toget) s_toget = bsize; - memcpy(buf, (m_wback+m_wbackcur-bsize), s_toget); + memcpy(buf, (m_wback+m_wbackcur), s_toget); - m_wbackcur -= s_toget; - if (m_wbackcur == 0) { + m_wbackcur += s_toget; + if (m_wbackcur == m_wbacksize) { free(m_wback); m_wback = (char *)NULL; m_wbacksize = 0; diff --git a/utils/wxMMedia2/README b/utils/wxMMedia2/README index 05faac97fe..e69de29bb2 100644 --- a/utils/wxMMedia2/README +++ b/utils/wxMMedia2/README @@ -1,8 +0,0 @@ -To build Makefile with automake: - in the top source directory type: - automake utils/wxMMedia2/Makefile - in the top build directory type: - mkdir -p utils/wxMMedia2 - CONFIG_FILES="utils/wxMMedia2/Makefile utils/wxMMedia2/lib/Makefile utils/wxMMedia2/sample/Makefile" CONFIG_HEADERS= ./config.status - -and then you can run make in utils/wxMMedia2. diff --git a/utils/wxMMedia2/lib/sndaiff.cpp b/utils/wxMMedia2/lib/sndaiff.cpp index bfcb149f8c..674141f653 100644 --- a/utils/wxMMedia2/lib/sndaiff.cpp +++ b/utils/wxMMedia2/lib/sndaiff.cpp @@ -42,6 +42,44 @@ wxSoundAiff::~wxSoundAiff() { } +bool wxSoundAiff::CanRead() +{ + wxUint32 signature1, signature2, len; + + if (m_input->Read(&signature1, 4).LastRead() != 4) + return FALSE; + + if (wxUINT32_SWAP_ON_BE(signature1) != FORM_SIGNATURE) { + m_input->Ungetch(&signature1, 4); + return FALSE; + } + + m_input->Read(&len, 4); + if (m_input->LastRead() != 4) { + m_input->Ungetch(&len, m_input->LastRead()); + m_input->Ungetch(&signature1, 4); + return FALSE; + } + + if (m_input->Read(&signature2, 4).LastRead() != 4) { + m_input->Ungetch(&signature2, m_input->LastRead()); + m_input->Ungetch(&len, 4); + m_input->Ungetch(&signature1, 4); + return FALSE; + } + + m_input->Ungetch(&signature2, 4); + m_input->Ungetch(&len, 4); + m_input->Ungetch(&signature1, 4); + + if ( + wxUINT32_SWAP_ON_BE(signature2) != AIFF_SIGNATURE && + wxUINT32_SWAP_ON_BE(signature2) != AIFC_SIGNATURE) + return FALSE; + + return TRUE; +} + #define FAIL_WITH(condition, err) if (condition) { m_snderror = err; return FALSE; } bool wxSoundAiff::PrepareToPlay() diff --git a/utils/wxMMedia2/lib/sndaiff.h b/utils/wxMMedia2/lib/sndaiff.h index 3f88a1a84e..bd9750380b 100644 --- a/utils/wxMMedia2/lib/sndaiff.h +++ b/utils/wxMMedia2/lib/sndaiff.h @@ -27,6 +27,8 @@ class wxSoundAiff: public wxSoundFileStream { wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound); ~wxSoundAiff(); + bool CanRead(); + protected: bool PrepareToPlay(); bool PrepareToRecord(unsigned long time); diff --git a/utils/wxMMedia2/lib/sndbase.h b/utils/wxMMedia2/lib/sndbase.h index 50e57c7e80..0f4fa4d8b7 100644 --- a/utils/wxMMedia2/lib/sndbase.h +++ b/utils/wxMMedia2/lib/sndbase.h @@ -119,9 +119,6 @@ class wxSoundStream { char *m_cdata[2]; protected: - // Do the async stuff. - void DoAsyncStuff(int evt); - // Handles event virtual void OnSoundEvent(int evt); }; diff --git a/utils/wxMMedia2/lib/sndcodec.cpp b/utils/wxMMedia2/lib/sndcodec.cpp index a21281b7b5..bef4e8326a 100644 --- a/utils/wxMMedia2/lib/sndcodec.cpp +++ b/utils/wxMMedia2/lib/sndcodec.cpp @@ -36,3 +36,8 @@ void wxSoundStreamCodec::SetDuplexMode(bool duplex) { m_sndio->SetDuplexMode(duplex); } + +wxUint32 wxSoundStreamCodec::GetBestSize() const +{ + return m_sndio->GetBestSize(); +} diff --git a/utils/wxMMedia2/lib/sndcodec.h b/utils/wxMMedia2/lib/sndcodec.h index 209dc91da2..841d24677b 100644 --- a/utils/wxMMedia2/lib/sndcodec.h +++ b/utils/wxMMedia2/lib/sndcodec.h @@ -23,6 +23,7 @@ class wxSoundStreamCodec: public wxSoundStream { bool StopProduction(); void SetDuplexMode(bool duplex); + wxUint32 GetBestSize() const; protected: wxSoundStream *m_sndio; diff --git a/utils/wxMMedia2/lib/sndcpcm.cpp b/utils/wxMMedia2/lib/sndcpcm.cpp index a6f0a18d07..27dba75dfd 100644 --- a/utils/wxMMedia2/lib/sndcpcm.cpp +++ b/utils/wxMMedia2/lib/sndcpcm.cpp @@ -59,6 +59,12 @@ wxSoundStreamPcm::ConverterType s_convert_out_8[] = { Convert_U2S_8, Convert_U2S_8, NULL +/*, + Convert_U2S_S2M_8, + Convert_U2S_S2M_8, + Convert_U2S_S2M_8, + Convert_U2S_S2M_8, + Convert_S2M_8 */ }; wxSoundStreamPcm::ConverterType s_convert_in_8_to_16[] = { @@ -80,6 +86,17 @@ wxSoundStreamPcm::ConverterType *s_convert_in_8 = s_convert_out_8; #define CONVERTER_SWAP_SIGN_SWAP 3 #define CONVERTER_SWAP_SIGN 4 #define CONVERTER_SWAP 5 +#define CONVERTER_SIGN_STEREO_MONO 6 +#define CONVERTER_SIGN_SWAP_STEREO_MONO 7 +#define CONVERTER_SWAP_SIGN_SWAP_STEREO_MONO 8 +#define CONVERTER_SWAP_SIGN_STEREO_MONO 9 +#define CONVERTER_SWAP_STEREO_MONO 10 +#define CONVERTER_STEREO_MONO 11 + +// +// TODO: Read() and Write() aren't really safe. If you give it a buffer which +// is not aligned on 8, you may crash (See converter.def). +// wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len) { diff --git a/utils/wxMMedia2/lib/sndesd.cpp b/utils/wxMMedia2/lib/sndesd.cpp index 85314f40c3..b31dfd1250 100644 --- a/utils/wxMMedia2/lib/sndesd.cpp +++ b/utils/wxMMedia2/lib/sndesd.cpp @@ -28,8 +28,9 @@ 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); + m_fd = esd_play_stream(ESD_PLAY | ESD_STREAM | ESD_MONO | ESD_BITS8, 22050, +// hostname.mb_str(), MY_ESD_NAME); + NULL, MY_ESD_NAME); if (m_fd == -1) { m_snderror = wxSOUND_INVDEV; @@ -44,6 +45,7 @@ wxSoundStreamESD::wxSoundStreamESD(const wxString& hostname) m_snderror = wxSOUND_NOERR; m_esd_stop = TRUE; + m_q_filled = TRUE; } wxSoundStreamESD::~wxSoundStreamESD() @@ -77,6 +79,8 @@ wxSoundStream& wxSoundStreamESD::Write(const void *buffer, wxUint32 len) else m_snderror = wxSOUND_NOERR; + m_q_filled = TRUE; + return *this; } @@ -136,6 +140,7 @@ static void _wxSound_OSS_CBack(gpointer data, int source, void wxSoundStreamESD::WakeUpEvt(int evt) { + m_q_filled = FALSE; OnSoundEvent(evt); } @@ -154,11 +159,11 @@ bool wxSoundStreamESD::StartProduction(int evt) if (evt == wxSOUND_OUTPUT) { flag |= ESD_PLAY | ESD_STREAM; - m_fd = esd_play_stream(flag, pcm->GetSampleRate(), m_hostname.mb_str(), + m_fd = esd_play_stream(flag, pcm->GetSampleRate(), NULL, MY_ESD_NAME); } else { flag |= ESD_RECORD | ESD_STREAM; - m_fd = esd_record_stream(flag, pcm->GetSampleRate(), m_hostname.mb_str(), + m_fd = esd_record_stream(flag, pcm->GetSampleRate(), NULL, MY_ESD_NAME); } @@ -170,6 +175,7 @@ bool wxSoundStreamESD::StartProduction(int evt) #endif m_esd_stop = FALSE; + m_q_filled = FALSE; return TRUE; } @@ -182,6 +188,7 @@ bool wxSoundStreamESD::StopProduction() gdk_input_remove(m_tag); esd_close(m_fd); m_esd_stop = TRUE; + m_q_filled = TRUE; return TRUE; } diff --git a/utils/wxMMedia2/lib/sndesd.h b/utils/wxMMedia2/lib/sndesd.h index 19e8c95d5e..5484f9dc37 100644 --- a/utils/wxMMedia2/lib/sndesd.h +++ b/utils/wxMMedia2/lib/sndesd.h @@ -37,11 +37,14 @@ class wxSoundStreamESD : public wxSoundStream { // You should not call this. void WakeUpEvt(int evt); + + bool QueueFilled() const { return m_q_filled; } protected: int m_fd; int m_tag; bool m_esd_stop; wxString m_hostname; + bool m_q_filled; private: void DetectBest(wxSoundFormatPcm *pcm); diff --git a/utils/wxMMedia2/lib/sndfile.cpp b/utils/wxMMedia2/lib/sndfile.cpp index 1234726300..b1be59501f 100644 --- a/utils/wxMMedia2/lib/sndfile.cpp +++ b/utils/wxMMedia2/lib/sndfile.cpp @@ -92,6 +92,14 @@ bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format) return TRUE; } +wxUint32 wxSoundRouterStream::GetBestSize() const +{ + if (m_router) + return m_router->GetBestSize(); + else + return m_sndio->GetBestSize(); +} + bool wxSoundRouterStream::StartProduction(int evt) { if (!m_router) { @@ -268,7 +276,7 @@ bool wxSoundFileStream::StopProduction() void wxSoundFileStream::OnSoundEvent(int evt) { - wxUint32 len = m_sndio->GetBestSize(); + wxUint32 len = m_codec.GetBestSize(); char *buffer; buffer = new char[len]; @@ -285,6 +293,7 @@ void wxSoundFileStream::OnSoundEvent(int evt) m_len -= len; if (m_len == 0) { Stop(); + delete[] buffer; return; } break; @@ -292,6 +301,7 @@ void wxSoundFileStream::OnSoundEvent(int evt) len = GetData(buffer, len); if (len == 0) { Stop(); + delete[] buffer; return; } m_codec.Write(buffer, len); diff --git a/utils/wxMMedia2/lib/sndfile.h b/utils/wxMMedia2/lib/sndfile.h index d710a2f1a6..10e77f8610 100644 --- a/utils/wxMMedia2/lib/sndfile.h +++ b/utils/wxMMedia2/lib/sndfile.h @@ -33,6 +33,8 @@ class WXDLLEXPORT wxSoundRouterStream: public wxSoundStreamCodec { bool StartProduction(int evt); bool StopProduction(); + wxUint32 GetBestSize() const; + protected: wxSoundStream *m_router; }; @@ -74,7 +76,7 @@ class wxSoundFileStream: public wxSoundStream { bool SetSoundFormat(const wxSoundFormatBase& format); - virtual bool CanRead() { return TRUE; } + virtual bool CanRead() { return FALSE; } protected: wxSoundRouterStream m_codec; diff --git a/utils/wxMMedia2/lib/sndg72x.cpp b/utils/wxMMedia2/lib/sndg72x.cpp index 798c0bc665..37d6c4453f 100644 --- a/utils/wxMMedia2/lib/sndg72x.cpp +++ b/utils/wxMMedia2/lib/sndg72x.cpp @@ -123,6 +123,33 @@ wxSoundStreamG72X::~wxSoundStreamG72X() wxSoundStream& wxSoundStreamG72X::Read(void *buffer, wxUint32 len) { + wxUint16 *old_linear; + register wxUint16 *linear_buffer; + register wxUint32 real_len; + register wxUint32 countdown = len; + + real_len = (len * 8 / m_n_bits); + + old_linear = linear_buffer = new wxUint16[real_len]; + + m_router->Read(linear_buffer, real_len); + + real_len = (wxUint32)(m_router->GetLastAccess() * ((float)m_n_bits / 8)); + if (!real_len) + return *m_router; + + m_io_buffer = (wxUint8 *)buffer; + m_current_b_pos = 0; + + while (countdown != 0) { + PutBits(m_coder(*linear_buffer++, AUDIO_ENCODING_LINEAR, m_state)); + countdown--; + } + m_lastcount = real_len; + m_snderror = m_router->GetError(); + + delete[] old_linear; + return *this; } @@ -133,22 +160,27 @@ wxSoundStream& wxSoundStreamG72X::Write(const void *buffer, wxUint32 len) register wxUint32 countdown = len; register wxUint32 real_len; - real_len = (wxUint32)(len * ((float)m_n_bits / 8)); + // Compute the real length (PCM format) to sendt to the sound card + real_len = (len * m_n_bits / 8); + // Allocate a temporary buffer old_linear = linear_buffer = new wxUint16[real_len]; // Bad, we override the const m_io_buffer = (wxUint8 *)buffer; m_current_b_pos = 0; + // Decode the datas while (countdown != 0) { *linear_buffer++ = m_decoder(GetBits(), AUDIO_ENCODING_LINEAR, m_state); countdown--; } m_lastcount = len; + // Send them to the sound card m_router->Write(old_linear, real_len); + // Destroy the temporary buffer delete[] old_linear; return *m_router; @@ -168,12 +200,14 @@ bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format) g72x = (wxSoundFormatG72X *)m_sndformat; + // Set PCM as the output format of the codec pcm.SetSampleRate(g72x->GetSampleRate()); pcm.SetBPS(16); pcm.SetChannels(1); pcm.Signed(TRUE); pcm.SetOrder(wxBYTE_ORDER); + // Look for the correct codec to use and set its bit width switch (g72x->GetG72XType()) { case wxSOUND_G721: m_n_bits = 4; @@ -192,6 +226,7 @@ bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format) break; } + // Let the router finish the work m_router->SetSoundFormat(pcm); return TRUE; diff --git a/utils/wxMMedia2/lib/sndulaw.cpp b/utils/wxMMedia2/lib/sndulaw.cpp index 620abb7aa1..5fb3153f9c 100644 --- a/utils/wxMMedia2/lib/sndulaw.cpp +++ b/utils/wxMMedia2/lib/sndulaw.cpp @@ -109,6 +109,11 @@ wxSoundStream& wxSoundStreamUlaw::Write(const void *buffer, wxUint32 len) return *m_router; } +wxUint32 wxSoundStreamUlaw::GetBestSize() const +{ + return m_sndio->GetBestSize() / 2; +} + bool wxSoundStreamUlaw::SetSoundFormat(const wxSoundFormatBase& format) { if (format.GetType() != wxSOUND_ULAW) { diff --git a/utils/wxMMedia2/lib/sndulaw.h b/utils/wxMMedia2/lib/sndulaw.h index 67129da083..8b2487a6d9 100644 --- a/utils/wxMMedia2/lib/sndulaw.h +++ b/utils/wxMMedia2/lib/sndulaw.h @@ -54,6 +54,8 @@ class WXDLLEXPORT wxSoundStreamUlaw: public wxSoundStreamCodec { bool SetSoundFormat(const wxSoundFormatBase& format); + wxUint32 GetBestSize() const; + protected: wxSoundRouterStream *m_router; }; diff --git a/utils/wxMMedia2/lib/sndwav.cpp b/utils/wxMMedia2/lib/sndwav.cpp index 79c1d20257..618cbfcab3 100644 --- a/utils/wxMMedia2/lib/sndwav.cpp +++ b/utils/wxMMedia2/lib/sndwav.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "sndbase.h" #include "sndcodec.h" @@ -51,28 +52,26 @@ wxSoundWave::~wxSoundWave() bool wxSoundWave::CanRead() { - wxUint32 len, signature; + wxUint32 len, signature1, signature2; m_snderror = wxSOUND_NOERR; - FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM); + FAIL_WITH(m_input->Read(&signature1, 4).LastRead() != 4, wxSOUND_INVSTRM); - if (wxUINT32_SWAP_ON_BE(signature) != RIFF_SIGNATURE) { - m_input->Ungetch(&signature, 4); + if (wxUINT32_SWAP_ON_BE(signature1) != RIFF_SIGNATURE) { + m_input->Ungetch(&signature1, 4); return FALSE; } m_input->Read(&len, 4); FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM); - FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM); - if (wxUINT32_SWAP_ON_BE(signature) != WAVE_SIGNATURE) { - m_input->Ungetch(&signature, 4); - return FALSE; - } - - m_input->Ungetch("RIFF", 4); + FAIL_WITH(m_input->Read(&signature2, 4).LastRead() != 4, wxSOUND_INVSTRM); + m_input->Ungetch(&signature2, 4); m_input->Ungetch(&len, 4); - m_input->Ungetch("WAVE", 4); + m_input->Ungetch(&signature1, 4); + + if (wxUINT32_SWAP_ON_BE(signature2) != WAVE_SIGNATURE) + return FALSE; return TRUE; } @@ -234,12 +233,13 @@ wxSoundFormatBase *wxSoundWave::HandleInputG72X(wxDataOutputStream& data) bool wxSoundWave::PrepareToRecord(unsigned long time) { -#define WRITE_SIGNATURE(sig) \ +#define WRITE_SIGNATURE(s,sig) \ signature = sig; \ signature = wxUINT32_SWAP_ON_BE(signature); \ -FAIL_WITH(m_output->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM); +FAIL_WITH(s->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM); - wxUint32 signature, len; + wxUint32 signature; + wxMemoryOutputStream fmt_data; if (!m_output) { m_snderror = wxSOUND_INVSTRM; @@ -247,30 +247,28 @@ FAIL_WITH(m_output->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM); } wxDataOutputStream data(*m_output); - data.BigEndianOrdered(FALSE); + wxDataOutputStream fmt_d_data(fmt_data); - len = m_sndformat->GetBytesFromTime(time); - - len += HEADER_SIZE; + data.BigEndianOrdered(FALSE); + fmt_d_data.BigEndianOrdered(FALSE); - WRITE_SIGNATURE(RIFF_SIGNATURE); + WRITE_SIGNATURE(m_output, RIFF_SIGNATURE); - data << len; FAIL_WITH(m_output->LastWrite() != 4, wxSOUND_INVSTRM); - WRITE_SIGNATURE(WAVE_SIGNATURE); + WRITE_SIGNATURE((&fmt_data), WAVE_SIGNATURE); { wxSoundFormatBase *frmt; - WRITE_SIGNATURE(FMT_SIGNATURE); + WRITE_SIGNATURE((&fmt_data), FMT_SIGNATURE); switch (m_sndformat->GetType()) { case wxSOUND_PCM: - frmt = HandleInputPCM(data); + frmt = HandleInputPCM(fmt_d_data); break; case wxSOUND_G72X: - frmt = HandleInputG72X(data); + frmt = HandleInputG72X(fmt_d_data); break; default: m_snderror = wxSOUND_NOCODEC; @@ -287,7 +285,19 @@ FAIL_WITH(m_output->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM); delete frmt; } - WRITE_SIGNATURE(DATA_SIGNATURE); + data << (fmt_data.GetSize() + 8 + m_sndformat->GetBytesFromTime(time)); + + { + char *out_buf; + out_buf = new char[fmt_data.GetSize()]; + + fmt_data.CopyTo(out_buf, fmt_data.GetSize()); + m_output->Write(out_buf, fmt_data.GetSize()); + + delete[] out_buf; + } + + WRITE_SIGNATURE(m_output, DATA_SIGNATURE); data.Write32(m_sndformat->GetBytesFromTime(time)); return TRUE; } diff --git a/utils/wxMMedia2/lib/sndwin.cpp b/utils/wxMMedia2/lib/sndwin.cpp index d89af5f82a..d4b73f2370 100644 --- a/utils/wxMMedia2/lib/sndwin.cpp +++ b/utils/wxMMedia2/lib/sndwin.cpp @@ -51,7 +51,7 @@ struct _wxSoundInfoHeader { wxSoundStreamWin *m_driver; }; -#define WXSOUND_MAX_QUEUE 128 +#define WXSOUND_MAX_QUEUE 10 wxSoundStreamWin::wxSoundStreamWin() { @@ -84,10 +84,12 @@ LRESULT APIENTRY _EXPORT _wxSoundHandlerWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { - case MM_WOM_DONE: { - wxFindSoundFromHandle((WXHWND)hWnd)->NotifyDoneBuffer(wParam); + case MM_WOM_DONE: + wxFindSoundFromHandle((WXHWND)hWnd)->NotifyDoneBuffer(wParam, wxSOUND_OUTPUT); + break; + case MM_WIM_DATA: + wxFindSoundFromHandle((WXHWND)hWnd)->NotifyDoneBuffer(wParam, wxSOUND_INPUT); break; - } default: break; } @@ -155,9 +157,9 @@ bool wxSoundStreamWin::OpenDevice(int mode) wformat.wFormatTag = WAVE_FORMAT_PCM; wformat.nChannels = pcm->GetChannels(); - wformat.nBlockAlign = pcm->GetBPS() / 8 * wformat.nChannels; - wformat.nAvgBytesPerSec = pcm->GetBytesFromTime(1); + wformat.nBlockAlign = wformat.nChannels * pcm->GetBPS() / 8; wformat.nSamplesPerSec = pcm->GetSampleRate(); + wformat.nAvgBytesPerSec = wformat.nSamplesPerSec * wformat.nBlockAlign; wformat.wBitsPerSample = pcm->GetBPS(); wformat.cbSize = 0; @@ -198,16 +200,25 @@ bool wxSoundStreamWin::OpenDevice(int mode) return FALSE; } - m_input_frag_in = WXSOUND_MAX_QUEUE-1; - m_current_frag_in = 0; + m_current_frag_in = WXSOUND_MAX_QUEUE-1; + m_input_frag_in = 0; m_internal->m_input_enabled = TRUE; } - if (!AllocHeaders(mode)) { - CloseDevice(); - return FALSE; + if (mode & wxSOUND_OUTPUT) { + if (!AllocHeaders(wxSOUND_OUTPUT)) { + CloseDevice(); + return FALSE; + } } + if (mode & wxSOUND_INPUT) { + if (!AllocHeaders(wxSOUND_INPUT)) { + CloseDevice(); + return FALSE; + } + } + return TRUE; } @@ -217,20 +228,20 @@ bool wxSoundStreamWin::OpenDevice(int mode) // ------------------------------------------------------------------------- void wxSoundStreamWin::CloseDevice() { + m_internal->m_output_enabled = FALSE; + m_internal->m_input_enabled = FALSE; + if (m_internal->m_output_enabled) { - FreeHeaders(wxSOUND_OUTPUT); waveOutReset(m_internal->m_devout); + FreeHeaders(wxSOUND_OUTPUT); waveOutClose(m_internal->m_devout); } if (m_internal->m_input_enabled) { - FreeHeaders(wxSOUND_INPUT); waveInReset(m_internal->m_devin); + FreeHeaders(wxSOUND_INPUT); waveInClose(m_internal->m_devin); } - - m_internal->m_output_enabled = FALSE; - m_internal->m_input_enabled = FALSE; } // ------------------------------------------------------------------------- @@ -412,15 +423,17 @@ void wxSoundStreamWin::FreeHeaders(int mode) // ------------------------------------------------------------------------- void wxSoundStreamWin::WaitFor(wxSoundInfoHeader *info) { - // We begun filling it: we must send it to the Windows queue - if (info->m_position != 0) { - memset(info->m_data + info->m_position, 0, info->m_size-info->m_position); - AddToQueue(info); - } - // If the buffer is finished, we return immediately - if (!info->m_playing && !info->m_recording) + if (!info->m_playing) { + + // We begun filling it: we must send it to the Windows queue + if (info->m_position != 0) { + memset(info->m_data + info->m_position, 0, info->m_size); + AddToQueue(info); + } + return; + } // Else, we wait for its termination while (info->m_playing || info->m_recording) @@ -443,7 +456,6 @@ bool wxSoundStreamWin::AddToQueue(wxSoundInfoHeader *info) if (info->m_mode == wxSOUND_INPUT) { // Increment the input fragment pointer - m_current_frag_in = (m_current_frag_in + 1) % WXSOUND_MAX_QUEUE; result = waveInAddBuffer(m_internal->m_devin, info->m_header, sizeof(WAVEHDR)); if (result == MMSYSERR_NOERROR) @@ -537,9 +549,11 @@ wxSoundInfoHeader *wxSoundStreamWin::NextFragmentInput() { wxSoundInfoHeader *header; - // TODO // header = m_headers_rec[m_current_frag_in]; - WaitFor(header); + if (header->m_recording) + WaitFor(header); + + m_current_frag_in = (m_current_frag_in + 1) % WXSOUND_MAX_QUEUE; if (m_current_frag_in == m_input_frag_in) m_queue_filled = TRUE; @@ -589,18 +603,25 @@ wxSoundStream& wxSoundStreamWin::Read(void *buffer, wxUint32 len) // fragment finished. It reinitializes the parameters of the fragment and // sends an event to the clients. // ------------------------------------------------------------------------- -void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle) +void wxSoundStreamWin::NotifyDoneBuffer(wxUint32 dev_handle, int flag) { wxSoundInfoHeader *info; - if (dev_handle == (wxUint32)m_internal->m_devout) { + if (flag == wxSOUND_OUTPUT) { + if (!m_internal->m_output_enabled) + return; + m_output_frag_out = (m_output_frag_out + 1) % WXSOUND_MAX_QUEUE; info = m_headers_play[m_output_frag_out]; ClearHeader(info); m_queue_filled = FALSE; OnSoundEvent(wxSOUND_OUTPUT); } else { + if (!m_internal->m_input_enabled) + return; + m_input_frag_in = (m_input_frag_in + 1) % WXSOUND_MAX_QUEUE; + m_headers_rec[m_input_frag_in]->m_recording = FALSE; OnSoundEvent(wxSOUND_INPUT); m_queue_filled = FALSE; } @@ -634,6 +655,8 @@ bool wxSoundStreamWin::StartProduction(int evt) int i; for (i=0;im_devin); } return TRUE; @@ -643,6 +666,9 @@ bool wxSoundStreamWin::StartProduction(int evt) // ------------------------------------------------------------------------- bool wxSoundStreamWin::StopProduction() { + if (m_internal->m_input_enabled) + waveInStop(m_internal->m_devin); + m_production_started = FALSE; CloseDevice(); return TRUE; diff --git a/utils/wxMMedia2/lib/sndwin.h b/utils/wxMMedia2/lib/sndwin.h index 549d533eaf..e6f979ed7d 100644 --- a/utils/wxMMedia2/lib/sndwin.h +++ b/utils/wxMMedia2/lib/sndwin.h @@ -31,7 +31,7 @@ class WXDLLEXPORT wxSoundStreamWin : public wxSoundStream { bool QueueFilled() const; // Internal but defined as public - void NotifyDoneBuffer(wxUint32 dev_handle); + void NotifyDoneBuffer(wxUint32 dev_handle, int flag); protected: wxSoundInternal *m_internal; diff --git a/utils/wxMMedia2/sample/test_med2.cpp b/utils/wxMMedia2/sample/test_med2.cpp index a6bc06ddaa..26b7dfaaf2 100644 --- a/utils/wxMMedia2/sample/test_med2.cpp +++ b/utils/wxMMedia2/sample/test_med2.cpp @@ -9,14 +9,16 @@ #include #include #include "../lib/sndoss.h" +#include "../lib/sndesd.h" #include "../lib/sndwav.h" #include "../lib/sndaiff.h" class MyApp: public wxApp { bool OnInit() { - wxSoundStreamOSS *oss_dev = new wxSoundStreamOSS(); +// wxSoundStreamOSS *oss_dev = new wxSoundStreamOSS(); + wxSoundStreamESD *oss_dev = new wxSoundStreamESD(); wxFileInputStream *f_input = new wxFileInputStream(argv[1]); - wxSoundFileStream *wav_file = new wxSoundAiff(*f_input, *oss_dev); + wxSoundFileStream *wav_file; wxFrame *frame = new wxFrame(NULL, -1, "My Frame"); wxSoundFormatPcm pcm; @@ -25,6 +27,13 @@ class MyApp: public wxApp { return FALSE; } + wav_file = new wxSoundWave(*f_input, *oss_dev); + if (!wav_file->CanRead()) { + wav_file = new wxSoundAiff(*f_input, *oss_dev); + if (!wav_file->CanRead()) + return FALSE; + } + wav_file->Play(); frame->Show(TRUE); return TRUE; -- 2.45.2