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

📄 wavein.cpp

📁 CIRRUS 93XX系列windows mobile 6.0 BSP
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//****************************************************************************
// 
// 
//
MMRESULT  WaveIn::Open
(
    WAVEOPENDESC        *pOpenDesc,
    DWORD               dwFlags
)    
{
    WAVEFORMATEX *      pFormat = pOpenDesc->lpFormat;
    MMRESULT            mmRet = MMSYSERR_NOERROR;
    ASSERT(pFormat);

    FUNC_WAVEIN((L"+WaveIn::Open"));

    if(dwFlags & WAVE_FORMAT_QUERY)
    {
        WIDM_MSG((L"Wave Format Query: \n"));
    }
    else
    {
        WIDM_MSG((L"Wave Format Open: \n"));
    }        
    WIDM_MSG((L"        nSamplesPerSec  = %d\n",pFormat->nSamplesPerSec));
    WIDM_MSG((L"        nChannels       = %d\n",pFormat->nChannels));
    WIDM_MSG((L"        wBitsPerSample  = %d\n",pFormat->wBitsPerSample));

    //
    // Allow PCM, mono or stereo, 8 or 16 bit at any frequency supported 
    // by the AC97 Codec.
    //
    if( (pFormat->wFormatTag != WAVE_FORMAT_PCM) ||
        (pFormat->nChannels  != 1      && pFormat->nChannels != 2) ||
        (pFormat->wBitsPerSample != 8  && pFormat->wBitsPerSample != 16))
    {
        mmRet = WAVERR_BADFORMAT;
    }
    
    //
    // Check to see if the sample rate is correct.
    //
    if(MMSUCCESS(mmRet))
    {
        if(m_pCodec->HasSRC())
        {
            switch( pFormat->nSamplesPerSec)
            {
                case 48000:
                case 44100:
                case 32000:
                case 22050:
                case 16000:
                case 11025:
                case 8000:
                    break;
                default:
                    mmRet = WAVERR_BADFORMAT;
                    break;
            }
        }
        else
        {
            switch( pFormat->nSamplesPerSec)
            {
                case 44100:
                case 22050:
                case 11025:
                case 8000:
                    break;
                default:
                    mmRet = WAVERR_BADFORMAT;
                    break;
            }
        }
    }
    
    //
    // If the Application is querying if we can play a certain format,
    // then just return.
    //
    if(dwFlags & WAVE_FORMAT_QUERY)
    {
        FUNC_WAVEIN((L"-WaveIn::Open\n"));
        return mmRet;
    }        

    //
    // Only one playback stream is allowed.
    //    
    if(m_pCodec->m_bRecordOpened)
    {
        mmRet = MMSYSERR_ALLOCATED;
    }
    
    //
    // Initialize the codec.
    //
    if(MMSUCCESS(mmRet))
    {
        if(m_pCodec->HasSRC())
        {
            mmRet = m_pCodec->SetRecordSampleRate(pFormat->nSamplesPerSec, 0);
        }
        else if(pFormat->nSamplesPerSec != 44100)
        {
            //
            // Get the settings for an external SRC.
            //
            int   iReturn;

            iReturn = SRCInit
            (
                &m_Src, 
                44100, 
                pFormat->nSamplesPerSec,
                (pFormat->wBitsPerSample == 8),
                (pFormat->nChannels ==1)
            );
            if(!iReturn)
            {
                mmRet = WAVERR_BADFORMAT;
            }
        }

        ASSERT(MMSUCCESS(mmRet));
    }            
    
    
    if (MMSUCCESS(mmRet))
    {
        m_WaveFormat            = *pFormat;
        m_dwRecordedBytes       = 0;
        m_bIsRecording          = FALSE;
        m_pfnCallback           = (DRVCALLBACK *) pOpenDesc->dwCallback;
        m_hCallback             = pOpenDesc->hWave;
        m_dwInstance            = pOpenDesc->dwInstance;
        m_pWaveHead             = 0;
        m_pWaveNext             = 0;
        m_dwDmaSampleSize       = m_pCodec->DmaSampleSize();


        //
        // Check to see if we are using an AC97 codec.  If so we have a sample
        // rate converter.
        //
        if(m_dwDmaSampleSize == 16)
        {
            m_dwSourceFactor = 2;

            if((pFormat->nChannels == 1) && (pFormat->wBitsPerSample == 8))
            {
                m_dwDestFactor      = 0;
                m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&ConvertShortsToBytesStereoToMono;
            }
            else if((pFormat->nChannels == 1) && (pFormat->wBitsPerSample == 16))
            {
                m_dwDestFactor      = 1;
                m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&ConvertShortsStereoToMono;
            }
            else if((pFormat->nChannels == 2) && (pFormat->wBitsPerSample == 8)) 
            {
                m_dwDestFactor      = 1;
                m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&ConvertShortsToBytes;
            }
            else if((pFormat->nChannels == 2) && (pFormat->wBitsPerSample == 16)) 
            {
                m_dwDestFactor      = 2;
                m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&ConvertShortsToShorts;
            }
            m_bUseSrc           = FALSE;
            m_pBuffer           = m_pDmaBuffer;
        }
        else if(pFormat->nSamplesPerSec == 44100)
        {
            m_dwSourceFactor = 3;
            if((pFormat->nChannels ==1) && (pFormat->wBitsPerSample == 8))
            {
                m_dwDestFactor      = 0;
                m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&ConvertWordsToBytesStereoToMono;
            }
            else if((pFormat->nChannels ==1) && (pFormat->wBitsPerSample == 16))
            {
                m_dwDestFactor      = 1;
                m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&ConvertWordsToShortsStereoToMono;
            }
            else if((pFormat->nChannels ==2) && (pFormat->wBitsPerSample == 8)) 
            {
                m_dwDestFactor      = 1;
                m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&ConvertWordsToBytes;
            }
            else if((pFormat->nChannels ==2) && (pFormat->wBitsPerSample == 16)) 
            {
                m_dwDestFactor      = 2;
                m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&ConvertWordsToShorts;
            }
            m_bUseSrc           = FALSE;
            m_pBuffer           = m_pDmaBuffer;
        }
        else
        {
            m_dwSourceFactor    = 3;
            m_dwDestFactor      = (pFormat->nChannels == 2) + (pFormat->wBitsPerSample == 16);
            m_pfnWaveCopyFunc   = (WaveInConversionFunc *)&Filter;
            m_bUseSrc           = TRUE;
            m_pBuffer           = PVOID(ULONG(m_pRateConverterBuffer) + 
                ((MAX_FILTER_SIZE) * sizeof(ULONG) * 2));
        }
        //else
        //{
        //    PRINTMSG
        //    (
        //        ZONE_ERROR, 
        //        (
        //            TEXT("ERROR: Did not catch bad format\r\n")
        //        )
        //    );
        //    mmRet = WAVERR_BADFORMAT;
        //}
    }        


    //
    // If there was no failures then the stream was allocated correctly.
    //
    if(MMSUCCESS(mmRet))
    {
        m_pCodec->m_bRecordOpened   = TRUE;

        //
        // Make the callback function call to the Wave API Manager
        //
        WIDM_MSG((L"WaveIn: WIM_OPEN\r\n"));
        m_pfnCallback(m_hCallback, MM_WIM_OPEN, m_dwInstance, 0, 0);
    }        

    //
    // Initialize the buffer to zero.
    //
    memset(m_pDmaBuffer,0,m_ulDmaBufferSize);


    FUNC_WAVEIN((L"-WaveIn::Open"));
    return(mmRet);
}

//****************************************************************************
// WaveIn::Reset
//****************************************************************************
// 
// 
//
MMRESULT    WaveIn::Reset()
{
    FUNC_WAVEIN((L"+WaveIn::Reset"));

    EnterCriticalSection( &m_CriticalSection);

    //
    // If we're recording, stop the DSP task
    //
    if(m_bIsRecording == TRUE)
    {
        m_pDma->Stop();
        Sleep(1);
        m_pCodec->StopRecord(0);
    }

    //
    // We're not recording anymore
    //
    m_bIsRecording = FALSE;

    //
    // Reset the wave device state
    //
    m_dwRecordedBytes = 0;

    //
    // Mark all buffers as done, return the buffers to the application and
    // initialize the list to zero.
    //

    MarkAllAsDone(m_pWaveHead);
    RemoveCompleteBlocks();
    m_pWaveNext = 0;



    LeaveCriticalSection( &m_CriticalSection);

    FUNC_WAVEIN((L"-WaveIn::Reset"));
    return(MMSYSERR_NOERROR);
}

//****************************************************************************
// WaveIn::Start
//****************************************************************************
// 
// 
//
MMRESULT  WaveIn::Start()
{
    FUNC_WAVEIN((L"+WaveIn::Start"));
    if(!m_bIsRecording)
    {
        m_bIsRecording = TRUE;

        //
        // If there is an Software SRC zero out the samples before the 
        // buffer.
        //
        if(m_bUseSrc)
        {
            memset
            (
                PULONG(m_pBuffer) - (m_Src.sFilterSize * 2),
                0,
                (2 * sizeof(ULONG) * m_Src.sFilterSize)
            );

        }

        m_pCodec->StartRecord(0);
        Sleep(1);
        m_pDma->Start();
    }

    FUNC_WAVEIN((L"-WaveIn::Start"));
    return(MMSYSERR_NOERROR);
}


//****************************************************************************
// WaveIn::Stop
//****************************************************************************
// 
// 
//
MMRESULT    WaveIn::Stop()
{
    WAVEHDR  *pWave;
    FUNC_WAVEIN((L"+WaveIn::Stop"));

    //
    // If not recording, ignore call according to  DDK
    // documentation.
    //
    if(m_bIsRecording)
    {
        m_bIsRecording = FALSE;
        m_pDma->Stop();
        Sleep(1);
        m_pCodec->StopRecord(0);

        //********************************************************************
        // When a WIDM_STOP occurs, this section of code marks the last buffer
        // as WIM_DONE even if the the buffer has no data copied into it.  It
        // also tells the application via a callback that the driver is
        // finished with the buffer in the header.
        //
        // We need to check to make sure that there is a buffer in the header.
        //********************************************************************
        if(m_pWaveHead)
        {
            pWave = m_pWaveHead;
            m_pWaveHead = m_pWaveHead->lpNext;

            //
            // If we release the buffer make sure it is not in the next queue.
            //
            if(pWave == m_pWaveNext)
            {
                m_pWaveNext = m_pWaveHead;
            }
            MARK_BUFFER_DONE(pWave);
            MARK_BUFFER_DEQUEUED(pWave);

            //
            // Make the callback function call to the Wave API Manager
            //
            m_pfnCallback
            (
                m_hCallback, 
                MM_WIM_DATA, 
                m_dwInstance, 
                (DWORD) pWave, 
                0
            );
        }

    }
    FUNC_WAVEIN((L"-WaveIn::Stop"));
    return(MMSYSERR_NOERROR);
}

//****************************************************************************
// ConvertWordsToBytes
//****************************************************************************
// Converts a stream of 24 bit Right justified words to bytes
//
// pUnused              - Unused pointer.
// pulSrc               - Signed 24 bit values right justified.
// pucDst               - Unsigned 8 bit values.
// pulSrcSamples        - IN/OUT Number of Source Samples Available/Used
// pulDstSamples        - IN/OUT Number of Destination Samples Available/Used
//
void ConvertWordsToBytes
(
    PVOID   pUnused,
    PULONG  pulSrc, 
    PUCHAR  pucDst, 
    PULONG  pulSrcSamples,
    PULONG  pulDstSamples
)
{
    ULONG   ulTemp;
    ULONG   ulSamples;
    PUCHAR  pucEnd;

    if(*pulSrcSamples > *pulDstSamples)
    {
        ulSamples = *pulSrcSamples = *pulDstSamples;
    }
    else
    {
        ulSamples = *pulDstSamples = *pulSrcSamples;
    }

    //
    // Copy the number of samples.  The samples are stereo
    // so we must copy both the right and left.
    //
    pucEnd = pucDst + (ulSamples<<1);    
    do
    {
        ulTemp          = *pulSrc++;
        *pucDst++ = UCHAR(ulTemp>>16) + 0x80;
    }
    while(pucDst < pucEnd);
    
}

//****************************************************************************
// ConvertWordsToShort
//****************************************************************************
// Converts a stream of bytes to words.
//
// pUnused              - Unused pointer.
// pulSrc               - Signed 24 bit values right justified.
// pusDst               - Signed 16 bit values.
// pulSrcSamples        - IN/OUT Number of Source Samples Available/Used
// pulDstSamples        - IN/OUT Number of Destination Samples Available/Used
//
void ConvertWordsToShorts
(
    PVOID       pUnused,
    PULONG      pulSrc, 
    PUSHORT     pusDst, 
    PULONG      pulSrcSamples,
    PULONG      pulDstSamples
)
{    
    ULONG       ulSamples;
    ULONG       ulTemp;
    PUSHORT     pusEnd;
    
    
    if(*pulSrcSamples > *pulDstSamples)
    {
        ulSamples = *pulSrcSamples = *pulDstSamples;
    }
    else
    {
        ulSamples = *pulDstSamples = *pulSrcSamples;
    }

    //
    // Copy the number of samples.  The samples are stereo
    // so we must copy both the right and left.
    //
    pusEnd = pusDst + (ulSamples<<1);    

⌨️ 快捷键说明

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