⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sndcpcm.cpp

📁 很牛的GUI源码wxWidgets-2.8.0.zip 可在多种平台下运行.
💻 CPP
字号:
// --------------------------------------------------------------------------// Name: sndcpcm.cpp// Purpose:// Date: 08/11/1999// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000// CVSID: $Id: sndcpcm.cpp,v 1.8 2005/09/23 12:47:51 MR Exp $// wxWindows licence// --------------------------------------------------------------------------#include "wx/wxprec.h"#ifndef WX_PRECOMP    #include "wx/defs.h"    #include "wx/debug.h"    #include "wx/log.h"#endif#ifdef __BORLANDC__    #pragma hdrstop#endif#include "wx/mmedia/sndbase.h"#include "wx/mmedia/sndpcm.h"#include "wx/mmedia/sndcpcm.h"wxSoundStreamPcm::wxSoundStreamPcm(wxSoundStream& sndio)        : wxSoundStreamCodec(sndio){    m_function_in = NULL;    m_function_out = NULL;    m_prebuffer = NULL;    m_prebuffer_size = 0;    m_best_size = 0;}wxSoundStreamPcm::~wxSoundStreamPcm(){    if (m_prebuffer)        delete[] m_prebuffer;}wxUint32 wxSoundStreamPcm::GetBestSize() const{    return m_best_size;}// -----------------------------------------------------------------------// "Converters" definitions/implementations// -----------------------------------------------------------------------#define DEFINE_CONV(name, input_type, output_type, convert) \static void Convert_##name(const void *buf_in, void *buf_out, wxUint32 len) \{\  register input_type src; \  register const input_type *t_buf_in = (input_type *)buf_in; \  register output_type *t_buf_out = (output_type *)buf_out; \\  while (len > 0) { \    src = *t_buf_in++; \    *t_buf_out++ = convert; \    len -= sizeof(input_type); \  } \}// TODO: define converters for all other formats (32, 24)DEFINE_CONV(8_8_sign, wxUint8, wxUint8, (src ^ 0x80))DEFINE_CONV(8_16, wxUint8, wxUint16, (((wxUint16)src) << 8))DEFINE_CONV(8_16_swap, wxUint8, wxUint16, (src))DEFINE_CONV(8_16_sign, wxUint8, wxUint16, (((wxUint16)(src ^ 0x80)) << 8))DEFINE_CONV(8_16_sign_swap, wxUint8, wxUint16, (src ^ 0x80))DEFINE_CONV(16_8, wxUint16, wxUint8, (wxUint8)(src >> 8))DEFINE_CONV(16_8_sign, wxUint16, wxUint8, (wxUint8)((src >> 8) ^ 0x80))DEFINE_CONV(16_swap_8, wxUint16, wxUint8, (wxUint8)(src & 0xff))DEFINE_CONV(16_swap_8_sign, wxUint16, wxUint8, (wxUint8)((src & 0xff) ^ 0x80))//DEFINE_CONV(24_8, wxUint32, wxUint8, (wxUint8)(src >> 16))//DEFINE_CONV(24_8_sig, wxUint32, wxUint8, (wxUint8)((src >> 16) ^ 0x80))//DEFINE_CONV(32_8, wxUint32, wxUint8, (wxUint8)(src >> 24))DEFINE_CONV(16_sign, wxUint16, wxUint16, (src ^ 0x8000))DEFINE_CONV(16_swap, wxUint16, wxUint16, (((src & 0xff) << 8) | ((src >> 8) & 0xff)))// Problem.DEFINE_CONV(16_swap_16_sign, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x80))// DEFINE_CONV(16_sign_16_swap, wxUint16, wxUint16, ((((src & 0xff) << 8) | ((src >> 8) & 0xff)) ^ 0x8000))DEFINE_CONV(16_swap_16_sign_swap, wxUint16, wxUint16, (src ^ 0x80))// -----------------------------------------------------------------------// Main PCM stream converter table// -----------------------------------------------------------------------// Definition//   XX -> YY//   XX -> YY sign////   XX swapped -> YY//   XX swapped -> YY sign////   XX swapped -> YY swapped//   XX swapped -> YY swapped sign////   XX stereo -> YY mono//   XX stereo -> YY mono sign////   XX swapped stereo -> YY swapped mono//   XX swapped stereo -> YY swapped mono sign////   XX swapped stereo -> YY swapped mono//   XX swapped stereo -> YY swapped mono signstatic wxSoundStreamPcm::ConverterType s_converters[4][3][2] = {     {        {            NULL,            Convert_8_8_sign                    /* 8 -> 8 sign */        },        {            NULL,            NULL        },        {            NULL,            NULL        }    },    {        {            Convert_8_16,                       /* 8 -> 16 */            Convert_8_16_sign                   /* 8 -> 16 sign */        },        {            Convert_8_16_swap,                  /* 8 -> 16 swapped */            Convert_8_16_sign_swap              /* 8 -> 16 sign swapped */        },        {            NULL,            NULL        }    },    {        {            Convert_16_8,                       /* 16 -> 8 */            Convert_16_8_sign                   /* 16 -> 8 sign */        },        {            Convert_16_swap_8,                  /* 16 swapped -> 8 */            Convert_16_swap_8_sign              /* 16 swapped -> 8 sign */        },        {            NULL,            NULL         },    },        {        {            NULL,                               /* 16 -> 16 */            Convert_16_sign                     /* 16 -> 16 sign */        },        {            Convert_16_swap,                    /* 16 swapped -> 16 */            Convert_16_swap_16_sign             /* 16 swapped -> 16 sign */        },        {            NULL,            Convert_16_swap_16_sign_swap        /* 16 swapped -> 16 sign swapped */        }    }};// This is the buffer size multiplier. It gives the needed size of the output size.static float s_converters_multip[] = {1, 2, 0.5, 1};//// TODO: Read() and Write() aren't really safe. If you give it a buffer which// is not aligned on 2, you may crash (See converter.def).//wxSoundStream& wxSoundStreamPcm::Read(void *buffer, wxUint32 len){    wxUint32 in_bufsize;    // We must have a multiple of 2    len &= 0x01;        if (!m_function_in) {        m_sndio->Read(buffer, len);        m_lastcount = m_sndio->GetLastAccess();        m_snderror = m_sndio->GetError();        return *this;    }    in_bufsize = GetReadSize(len);        if (len <= m_best_size) {        m_sndio->Read(m_prebuffer, in_bufsize);        m_snderror  = m_sndio->GetError();        if (m_snderror != wxSOUND_NOERROR) {            m_lastcount = 0;            return *this;        }                m_function_in(m_prebuffer, buffer, m_sndio->GetLastAccess());    } else {        char *temp_buffer;                temp_buffer = new char[in_bufsize];        m_sndio->Read(temp_buffer, in_bufsize);        m_snderror =  m_sndio->GetError();        if (m_snderror != wxSOUND_NOERROR) {            m_lastcount = 0;            return *this;        }                m_function_in(temp_buffer, buffer, m_sndio->GetLastAccess());                delete[] temp_buffer;    }        m_lastcount = (wxUint32)(m_sndio->GetLastAccess() * m_multiplier_in);        return *this;}wxSoundStream& wxSoundStreamPcm::Write(const void *buffer, wxUint32 len){    wxUint32 out_bufsize;        if (!m_function_out) {        m_sndio->Write(buffer, len);        m_lastcount = m_sndio->GetLastAccess();        m_snderror  = m_sndio->GetError();        return *this;    }    out_bufsize = GetWriteSize(len);    if (len <= m_best_size) {        out_bufsize = GetWriteSize(len);        m_function_out(buffer, m_prebuffer, len);        m_sndio->Write(m_prebuffer, out_bufsize);        m_snderror  = m_sndio->GetError();        if (m_snderror != wxSOUND_NOERROR) {            m_lastcount = 0;            return *this;        }    } else {        char *temp_buffer;                temp_buffer = new char[out_bufsize];        m_function_out(buffer, temp_buffer, len);                m_sndio->Write(temp_buffer, out_bufsize);        m_snderror =  m_sndio->GetError();        if (m_snderror != wxSOUND_NOERROR) {            m_lastcount = 0;            return *this;        }                delete[] temp_buffer;    }    m_lastcount = (wxUint32)(m_sndio->GetLastAccess() / m_multiplier_out);    return *this;}bool wxSoundStreamPcm::SetSoundFormat(const wxSoundFormatBase& format){    wxSoundFormatBase *new_format;    wxSoundFormatPcm *pcm_format, *pcm_format2;        if (m_sndio->SetSoundFormat(format)) {        m_function_out = NULL;        m_function_in = NULL;        return true;    }    if (format.GetType() != wxSOUND_PCM) {        m_snderror = wxSOUND_INVFRMT;        return false;    }    if (m_sndformat)        delete m_sndformat;        new_format = m_sndio->GetSoundFormat().Clone();    pcm_format = (wxSoundFormatPcm *)&format;    pcm_format2 = (wxSoundFormatPcm *)new_format;#if 0    // ----------------------------------------------------    // Test whether we need to resample    if (pcm_format->GetSampleRate() != pcm_format2->GetSampleRate()) {        wxUint32 src_rate, dst_rate;        src_rate = pcm_format->GetSampleRate();        dst_rate = pcm_format2->GetSampleRate();        m_needResampling = true;        if (src_rate < dst_rate)            m_expandSamples = true;        else            m_expandSamples = false;        m_pitch = (src_rate << FLOATBITS) / dst_rate;    }#endif    // ----------------------------------------------------    // Select table to use:    //     * 8 bits -> 8 bits    //     * 16 bits -> 8 bits    //     * 8 bits -> 16 bits    //     * 16 bits -> 16 bits    int table_no, table_no2;    int i_sign, i_swap;        switch (pcm_format->GetBPS()) {        case 8:            table_no = 0;            break;        case 16:            table_no = 1;            break;        default:            // TODO: Add something here: error, log, ...            return false;    }    switch (pcm_format2->GetBPS()) {        case 8:            table_no2 = 0;            break;        case 16:            table_no2 = 1;            break;        default:            // TODO: Add something here: error, log, ...            return false;    }        if (pcm_format2->Signed() != pcm_format->Signed())        i_sign = 1;    else        i_sign = 0;#define MY_ORDER wxBYTE_ORDER#if wxBYTE_ORDER == wxLITTLE_ENDIAN#define OTHER_ORDER wxBIG_ENDIAN#else#define OTHER_ORDER wxLITTLE_ENDIAN#endif    // --------------------------------------------------------    // Find the good converter !    if (pcm_format->GetOrder() == OTHER_ORDER) {        if (pcm_format->GetOrder() == pcm_format2->GetOrder())            i_swap = 2;        else            i_swap = 1;    } else {        if (pcm_format->GetOrder() == pcm_format2->GetOrder())            i_swap = 0;        else            i_swap = 1;    }    m_function_out = s_converters[table_no*2+table_no2][i_swap][i_sign];    m_function_in  = s_converters[table_no2*2+table_no][i_swap][i_sign];    m_multiplier_out = s_converters_multip[table_no*2+table_no2];    m_multiplier_in  = s_converters_multip[table_no2*2+table_no2];    if (m_prebuffer)        delete[] m_prebuffer;    // We try to minimize the need for dynamic memory allocation by preallocating a buffer. But    // to be sure it will be efficient we minimize the best size.    if (m_multiplier_in < m_multiplier_out) {        m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() *                                      m_multiplier_out);        m_best_size = (wxUint32)(m_sndio->GetBestSize() *                                 m_multiplier_in);    } else {        m_prebuffer_size = (wxUint32)(m_sndio->GetBestSize() *                                      m_multiplier_in);        m_best_size = (wxUint32)(m_sndio->GetBestSize() *                                 m_multiplier_out);    }        m_prebuffer = new char[m_prebuffer_size];        bool SetSoundFormatReturn;    SetSoundFormatReturn = m_sndio->SetSoundFormat(*new_format);    wxASSERT( SetSoundFormatReturn );    wxUnusedVar( SetSoundFormatReturn );        m_sndformat = new_format;    return true;}wxUint32 wxSoundStreamPcm::GetWriteSize(wxUint32 len) const{    // For the moment, it is simple but next time it will become more complicated    // (Resampling)    return (wxUint32)(len * m_multiplier_out);}wxUint32 wxSoundStreamPcm::GetReadSize(wxUint32 len) const{    return (wxUint32)(len / m_multiplier_in);}// Resampling engine. NOT FINISHED and NOT INCLUDED but this is a first DRAFT.#if 0#define FLOATBITS 16#define INTBITS 16#define FLOATMASK 0xffff#define INTMASK 0xffff0000void ResamplingShrink_##DEPTH##(const void *source, void *destination, wxUint32 len){    wxUint##DEPTH## *source_data, *dest_data;    wxUint32 pos;    source_data = (wxUint##DEPTH## *)source;    dest_data   = (wxUint##DEPTH## *)destination;        pos = m_saved_pos;    while (len > 0) {        // Increment the position in the input buffer        pos += m_pitch;        if (pos & INTMASK) {            pos &= FLOATMASK;                        *dest_data ++ = *source_data;        }        len--;        source_data++;    }    m_saved_pos = pos;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -