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

📄 input.cpp

📁 pxa270平台 windows mobile 5.2 wm9713 触摸屏+音频驱动
💻 CPP
字号:
//-----------------------------------------------------------------------------
// Copyright (c) Wolfson Microelectronics plc.  All rights reserved.
//
// This software as well as any related documentation is furnished under 
// license and may only be used or copied in accordance with the terms of the 
// license. The information in this file is furnished for informational use 
// only, is subject to change without notice, and should not be construed as 
// a commitment by Wolfson Microelectronics plc. Wolfson Microelectronics plc
// assumes no responsibility or liability for any errors or inaccuracies that
// may appear in this document or any software that may be provided in
// association with this document. 
//
// Except as permitted by such license, no part of this document may be 
// reproduced, stored in a retrieval system, or transmitted in any form or by 
// any means without the express written consent of Wolfson Microelectronics plc. 
//
// $Id: input.cpp 1796 2005-06-10 15:46:04Z ian $
//
// This file contains the code specific to input streams for the WaveDev2
// driver for Wolfson codecs.
//
// Warning:
//  This driver is specifically written for Wolfson Audio Codecs.  It is
//  not a general audio CODEC device driver.
//-----------------------------------------------------------------------------

//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// -----------------------------------------------------------------------------
//
//      THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//      ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//      PARTICULAR PURPOSE.
//
// -----------------------------------------------------------------------------
#include "wavemain.h"

//-----------------------------------------------------------------------------
// Member function:    SetRate
//
// Init input m_DeltaT with (HWSampleRate/SampleRate) calculated in fixed point form.
// Note that we need to hold the result in a 64-bit value until we're done shifting,
// since the result of the multiply will overflow 32 bits for sample rates greater than
// or equal to the hardware's sample rate.
//
// Parameters:
//		dwMultiplier    Multiplier in fixed point format
//                      e.g 16.16 format (0x1000 => x 1.000)
//
// Returns:     DWORD
//		Always MMSYSERR_NOERROR
//-----------------------------------------------------------------------------
DWORD InputStreamContext::SetRate(DWORD dwMultiplier)
{
    UINT64 Delta;

    m_dwMultiplier = dwMultiplier;

    Delta = (m_WaveFormat.nSamplesPerSec * m_dwMultiplier);
    Delta >>= 16;
    Delta = ((UINT32)(((1i64<<32)/Delta)+1));
    Delta = (Delta * SampleRate());
    Delta >>= DELTAINT;
    m_DeltaT = (DWORD)Delta;
    return MMSYSERR_NOERROR;
}

//-----------------------------------------------------------------------------
// Member function:    Stop
//
// Stops streaming from the codec and returns all buffers to the client.
//
// Parameters:
//		none
//
// Returns:     DWORD
//      Always MMSYSERR_NOERROR
//-----------------------------------------------------------------------------
DWORD InputStreamContext::Stop()
{
    // Stop the stream
    WaveStreamContext::Stop();

    // Return any partially filled buffers to the client
    if ((m_lpWaveHdrCurrent) && (m_lpWaveHdrCurrent->dwBytesRecorded>0))
    {
        GetNextBuffer();
    }

    return MMSYSERR_NOERROR;
}

//-----------------------------------------------------------------------------
// Member function:    StereoInputStreamContext::Render2
//
// This function renders the next buffer-full of data from the given buffer.
// This class renders from stereo.
//
// Parameters:
//      pBuffer     the start of the output buffer.
//      pBufferEnd  the end of the output buffer.
//      pBufferLast the current high-water mark in the buffer.  This is the
//                  furthest point in the buffer which has had data rendered
//                  from it.  This is more relevant to output streams, but is
//                  included here so that it can be a common virtual function.
//
// Returns:     PBYTE
//      The end point rendered by this stream.  This is used to update
//      pBufferLast when rendering several streams from the same buffer.
//-----------------------------------------------------------------------------
PBYTE StereoInputStreamContext::Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast)
{
    PBYTE pCurrData = m_lpCurrData;
    PBYTE pCurrDataEnd = m_lpCurrDataEnd;
#if defined(ENABLE_INPUT_GAIN)
    LONG fxpGain[2];
    fxpGain[0] = m_fxpGain[0];
    fxpGain[1] = m_fxpGain[1];
#endif

    LONG CurrT = m_CurrT;
    LONG DeltaT = m_DeltaT;
    PCM_TYPE SampleType = m_SampleType;

    LONG CurrSamp0 = m_CurrSamp[0];
    LONG PrevSamp0 = m_PrevSamp[0];
    LONG CurrSamp1 = m_CurrSamp[1];
    LONG PrevSamp1 = m_PrevSamp[1];
    LONG InSamp0;
    LONG InSamp1;

    for (;;)
    {
        // Make sure we have a place to put the data
        if (pCurrData>=pCurrDataEnd)
        {
            goto Exit;
        }

        // Get the next sample
        while (CurrT >= DELTA_OVERFLOW)
        {
            if (pBuffer>=pBufferEnd)
            {
                goto Exit;
            }

            PrevSamp0 = CurrSamp0;
            PrevSamp1 = CurrSamp1;

            CurrSamp0 = ((HWSAMPLE *)pBuffer)[0];
            CurrSamp1 = ((HWSAMPLE *)pBuffer)[1];
            pBuffer += 2*sizeof(HWSAMPLE);

            CurrT -= DELTA_OVERFLOW;
        }

        InSamp0 = (PrevSamp0 + ((CurrT * (CurrSamp0 - PrevSamp0)) >> DELTAFRAC));
        InSamp1 = (PrevSamp1 + ((CurrT * (CurrSamp1 - PrevSamp1)) >> DELTAFRAC));
        CurrT += DeltaT;

#if defined(ENABLE_INPUT_GAIN)
        // Apply input gain
        InSamp0 = (InSamp0 * fxpGain[0]) >> 16;
        InSamp1 = (InSamp1 * fxpGain[1]) >> 16;
#endif

        PPCM_SAMPLE pSampleDest = (PPCM_SAMPLE)pCurrData;
        switch (m_SampleType)
        {
        case PCM_TYPE_M8:
        default:
            pSampleDest->m8.sample = (UINT8)( ((InSamp0+InSamp1) >> 9) + 128);
            pCurrData  += 1;
            break;

        case PCM_TYPE_S8:
            pSampleDest->s8.sample_left  = (UINT8)((InSamp0 >> 8) + 128);
            pSampleDest->s8.sample_right = (UINT8)((InSamp1 >> 8) + 128);
            pCurrData  += 2;
            break;

        case PCM_TYPE_M16:
            pSampleDest->m16.sample = (INT16)((InSamp0+InSamp1)>>1);
            pCurrData  += 2;
            break;

        case PCM_TYPE_S16:
            pSampleDest->s16.sample_left  = (INT16)InSamp0;
            pSampleDest->s16.sample_right = (INT16)InSamp1;
            pCurrData  += 4;
            break;
        }
    }

Exit:
    m_lpWaveHdrCurrent->dwBytesRecorded += (pCurrData-m_lpCurrData);
    m_dwByteCount += (pCurrData-m_lpCurrData);
    m_lpCurrData = pCurrData;
    m_CurrT = CurrT;
    m_PrevSamp[0] = PrevSamp0;
    m_CurrSamp[0] = CurrSamp0;
    m_PrevSamp[1] = PrevSamp1;
    m_CurrSamp[1] = CurrSamp1;
    return pBuffer;
}

//-----------------------------------------------------------------------------
// Member function:    MonoInputStreamContext::Render2
//
// This function renders the next buffer-full of data from the given buffer.
// This class renders from stereo.
//
// Parameters:
//      pBuffer     the start of the output buffer.
//      pBufferEnd  the end of the output buffer.
//      pBufferLast the current high-water mark in the buffer.  This is the
//                  furthest point in the buffer which has had data rendered
//                  from it.  This is more relevant to output streams, but is
//                  included here so that it can be a common virtual function.
//
// Returns:     PBYTE
//      The end point rendered by this stream.  This is used to update
//      pBufferLast when rendering several streams from the same buffer.
//-----------------------------------------------------------------------------
PBYTE MonoInputStreamContext::Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast)
{
    PBYTE pCurrData = m_lpCurrData;
    PBYTE pCurrDataEnd = m_lpCurrDataEnd;
#if defined(ENABLE_INPUT_GAIN)
    LONG fxpGain = m_fxpGain[0];
#endif

    LONG CurrT = m_CurrT;
    LONG DeltaT = m_DeltaT;

    LONG CurrSamp0 = m_CurrSamp[0];
    LONG PrevSamp0 = m_PrevSamp[0];
    LONG InSamp0;

    PCM_TYPE SampleType = m_SampleType;

    for (;;)
    {
        // Make sure we have a place to put the data
        if (pCurrData>=pCurrDataEnd)
        {
            goto Exit;
        }

        // Get the next sample
        while (CurrT >= DELTA_OVERFLOW)
        {
            if (pBuffer>=pBufferEnd)
            {
                goto Exit;
            }

            PrevSamp0 = CurrSamp0;
            CurrSamp0 = *(HWSAMPLE *)pBuffer;
            pBuffer += sizeof(HWSAMPLE);

            CurrT -= DELTA_OVERFLOW;
        }

        InSamp0 = (PrevSamp0 + ((CurrT * (CurrSamp0 - PrevSamp0)) >> DELTAFRAC));

        CurrT += DeltaT;

#if defined(ENABLE_INPUT_GAIN)
        // Apply input gain
        InSamp0 = (InSamp0 * fxpGain) >> 16;
#endif

        PPCM_SAMPLE pSampleDest = (PPCM_SAMPLE)pCurrData;
        switch (m_SampleType)
        {
        case PCM_TYPE_M8:
        default:
            pSampleDest->m8.sample = (UINT8)((InSamp0 >> 8) + 128);
            pCurrData  += 1;
            break;

        case PCM_TYPE_S8:
            pSampleDest->s8.sample_left  = (UINT8)((InSamp0 >> 8) + 128);
            pSampleDest->s8.sample_right = (UINT8)((InSamp0 >> 8) + 128);
            pCurrData  += 2;
            break;

        case PCM_TYPE_M16:
            pSampleDest->m16.sample = (INT16)InSamp0;
            pCurrData  += 2;
            break;

        case PCM_TYPE_S16:
            pSampleDest->s16.sample_left  = (INT16)InSamp0;
            pSampleDest->s16.sample_right = (INT16)InSamp0;
            pCurrData  += 4;
            break;
        }
    }

Exit:
    m_lpWaveHdrCurrent->dwBytesRecorded += (pCurrData-m_lpCurrData);
    m_dwByteCount += (pCurrData-m_lpCurrData);
    m_lpCurrData = pCurrData;
    m_CurrT = CurrT;
    m_PrevSamp[0] = PrevSamp0;
    m_CurrSamp[0] = CurrSamp0;
    return pBuffer;
}

//------------------------------- END OF FILE ----------------------------------

⌨️ 快捷键说明

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