X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6c5e63761c870ea4918a3fe049f99fce6707b938..5b7352027902bebecd06e2a124492fc0ee27f4e2:/utils/wxMMedia2/lib/sndwav.cpp?ds=sidebyside diff --git a/utils/wxMMedia2/lib/sndwav.cpp b/utils/wxMMedia2/lib/sndwav.cpp index f0d3f66a29..618cbfcab3 100644 --- a/utils/wxMMedia2/lib/sndwav.cpp +++ b/utils/wxMMedia2/lib/sndwav.cpp @@ -14,11 +14,13 @@ #include #include #include +#include #include "sndbase.h" #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)) @@ -50,28 +52,59 @@ 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); + FAIL_WITH(m_input->Read(&signature2, 4).LastRead() != 4, wxSOUND_INVSTRM); + m_input->Ungetch(&signature2, 4); + m_input->Ungetch(&len, 4); + m_input->Ungetch(&signature1, 4); + + if (wxUINT32_SWAP_ON_BE(signature2) != WAVE_SIGNATURE) return FALSE; - } - m_input->Ungetch("RIFF", 4); - m_input->Ungetch(&len, 4); - m_input->Ungetch("WAVE", 4); + return TRUE; +} + +bool wxSoundWave::HandleOutputPCM(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::HandleOutputG721(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; } @@ -112,21 +145,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 (!HandleOutputPCM(data, channels, sample_fq, + byte_p_sec, byte_p_spl, bits_p_spl)) + return FALSE; + break; + case 0x40: + if (!HandleOutputG721(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" @@ -140,14 +177,69 @@ bool wxSoundWave::PrepareToPlay() return TRUE; } +wxSoundFormatBase *wxSoundWave::HandleInputPCM(wxDataOutputStream& data) +{ + wxUint16 format, channels, byte_p_spl, bits_p_spl; + wxUint32 sample_fq, byte_p_sec; + wxSoundFormatPcm *pcm; + + pcm = (wxSoundFormatPcm *)(m_sndformat->Clone()); + + // Write block length + data.Write32(16); + + sample_fq = pcm->GetSampleRate(); + bits_p_spl = pcm->GetBPS(); + channels = pcm->GetChannels(); + byte_p_spl = pcm->GetBPS() / 8; + byte_p_sec = pcm->GetBytesFromTime(1); + format = 0x01; + + pcm->Signed(TRUE); + pcm->SetOrder(wxLITTLE_ENDIAN); + + data << format << channels << sample_fq + << byte_p_sec << byte_p_spl << bits_p_spl; + + return pcm; +} + +wxSoundFormatBase *wxSoundWave::HandleInputG72X(wxDataOutputStream& data) +{ + wxUint16 format, channels, byte_p_spl, bits_p_spl; + wxUint32 sample_fq, byte_p_sec; + wxSoundFormatG72X *g72x; + + // Write block length + data.Write32(16); + + g72x = (wxSoundFormatG72X *)(m_sndformat->Clone()); + if (g72x->GetG72XType() != wxSOUND_G721) { + delete g72x; + return NULL; + } + + sample_fq = g72x->GetSampleRate(); + bits_p_spl = 4; + channels = 1; + byte_p_spl = 0; + byte_p_sec = g72x->GetBytesFromTime(1); + format = 0x40; + data << format << channels << sample_fq + << byte_p_sec << byte_p_spl << bits_p_spl; + + return g72x; +} + 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; @@ -155,53 +247,57 @@ FAIL_WITH(m_output->Write(&signature, 4).LastWrite() != 4, wxSOUND_INVSTRM); } wxDataOutputStream data(*m_output); - data.BigEndianOrdered(FALSE); - - len = m_sndformat->GetBytesFromTime(time); + wxDataOutputStream fmt_d_data(fmt_data); - 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); { - wxUint16 format, channels, byte_p_spl, bits_p_spl; - wxUint32 sample_fq, byte_p_sec; - wxSoundFormatPcm *pcm; + wxSoundFormatBase *frmt; + + WRITE_SIGNATURE((&fmt_data), FMT_SIGNATURE); - if (m_sndformat->GetType() != wxSOUND_PCM) { + switch (m_sndformat->GetType()) { + case wxSOUND_PCM: + frmt = HandleInputPCM(fmt_d_data); + break; + case wxSOUND_G72X: + frmt = HandleInputG72X(fmt_d_data); + break; + default: m_snderror = wxSOUND_NOCODEC; return FALSE; } - pcm = (wxSoundFormatPcm *)(m_sndformat->Clone()); + FAIL_WITH(!frmt, wxSOUND_NOCODEC); + + if (!SetSoundFormat(*frmt)) { + delete frmt; + return FALSE; + } + + delete frmt; + } - WRITE_SIGNATURE(FMT_SIGNATURE); - data.Write32(16); + data << (fmt_data.GetSize() + 8 + m_sndformat->GetBytesFromTime(time)); - sample_fq = pcm->GetSampleRate(); - bits_p_spl = pcm->GetBPS(); - channels = pcm->GetChannels(); - byte_p_spl = pcm->GetBPS() / 8; - byte_p_sec = pcm->GetBytesFromTime(1); - format = 1; - data << format << channels << sample_fq - << byte_p_sec << byte_p_spl << bits_p_spl; + { + char *out_buf; + out_buf = new char[fmt_data.GetSize()]; - pcm->Signed(TRUE); - pcm->SetOrder(wxLITTLE_ENDIAN); - - if (!SetSoundFormat(*pcm)) - return FALSE; + fmt_data.CopyTo(out_buf, fmt_data.GetSize()); + m_output->Write(out_buf, fmt_data.GetSize()); - delete pcm; + delete[] out_buf; } - WRITE_SIGNATURE(DATA_SIGNATURE); + WRITE_SIGNATURE(m_output, DATA_SIGNATURE); data.Write32(m_sndformat->GetBytesFromTime(time)); return TRUE; } @@ -212,12 +308,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(); }