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

📄 wavepdd.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
📖 第 1 页 / 共 5 页
字号:
//------------------------------------------------------------------------------------------------------------
VOID
private_AudioComplete(PWAVEHDR pwh, ULONG cbBytesCompleted)
{
    // we've just finished playing another cbDstBytes of data.
    // update the queued headers accordingly
    while ((pwh != NULL) && (cbBytesCompleted > 0)) {

        if (pwh->dwBytesRecorded >= pwh->reserved) {
            pwh = pwh->lpNext;
        }
        else {
            ULONG cbBytesLeft = pwh->reserved - pwh->dwBytesRecorded;
            ULONG cbAdvance = min(cbBytesCompleted, cbBytesLeft);
            cbBytesCompleted -= cbAdvance;
            pwh->dwBytesRecorded += cbAdvance;
        }
    }

}

VOID
FillBufferM08 (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples)
{
    while (dwSamples-- > 0) {
        PPCM_SAMPLE pSample = (PPCM_SAMPLE) pSrcBuffer;
        INT16 sample16 = BITS_8_TO_16(pSample->m8.sample);
        pDstBuffer[0] = sample16;
        pDstBuffer[1] = sample16;
        pDstBuffer += 2;
        pSrcBuffer += 1;
    }
}

VOID
FillBufferS08 (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples)
{
    while (dwSamples-- > 0) {
        PPCM_SAMPLE pSample = (PPCM_SAMPLE) pSrcBuffer;
        pDstBuffer[0] = BITS_8_TO_16(pSample->s8.sample_left);
        pDstBuffer[1] = BITS_8_TO_16(pSample->s8.sample_right);
        pDstBuffer += 2;
        pSrcBuffer += 2;
    }
}

VOID
FillBufferM16 (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples)
{
    while (dwSamples-- > 0) {
        INT16 sample = * (PINT16) pSrcBuffer;
        pDstBuffer[0] = sample;
        pDstBuffer[1] = sample;
        pDstBuffer += 2;
        pSrcBuffer += 2;
    }
}

VOID
FillBufferS16 (PINT16 pDstBuffer, PBYTE pSrcBuffer, DWORD dwSamples)
{
    memcpy(pDstBuffer, pSrcBuffer, dwSamples * sizeof(DWORD));
}


//------------------------------------------------------------------------------------------------------------
// Function: private_AudioFillBuffer
//
// Purpose: Copies (plays) audio data to the DMAC buffers from Windows CE application buffers.  The data is
//          reformatted to meet the requirements of the codec.  This function is called in response to the
//          WPDM_START or WPDM_CONTINUE messages where the WAPI_INOUT directin is WAPI_OUT.
//-------------------------------------------------------------------------------------------------------------
VOID
private_AudioFillBuffer (
    PWAVEHDR pwh,
    PDWORD pDstBuffer,
    DWORD dwDstSamples
    )
{

    FUNC_VERBOSE("+PDD_AudioFillBuffer");

    while ((pwh != NULL) && (dwDstSamples > 0)) {
        if (pwh->reserved >= pwh->dwBufferLength) {
            pwh = pwh->lpNext;
        }
        else {
            DWORD dwSrcSamples = (pwh->dwBufferLength - pwh->reserved) / g_sample_size[WAPI_OUT];
            DWORD dwSamples = min(dwDstSamples, dwSrcSamples);

            __try
            {
                g_pfnFillBuffer((PINT16) pDstBuffer, pwh->lpData + pwh->reserved, dwSamples);
            }
            __except (EXCEPTION_EXECUTE_HANDLER)
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("wavepdd: Handled buffer fault in private_AudioFillBuffer\r\n")));
            }

            pwh->reserved += dwSamples * g_sample_size[WAPI_OUT];
            pDstBuffer += dwSamples;
            dwDstSamples -= dwSamples;
        }
    }

    //the input buffer is out of data, pad the DMA buffer with zeros
    memset(pDstBuffer, 0, dwDstSamples * sizeof(DWORD));

}

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveOutEndOfData
//
// Purpose: Stops output of audio data.
//-------------------------------------------------------------------------------------------------------------
VOID
private_WaveOutEndOfData()
{
    FUNC_WPDD("+PDD_WaveOutEndOfData");

    //
    // There is no more data coming...
    //
    v_fMoreData[WAPI_OUT] = FALSE;

    StopDmac(DMA_CH_OUT);

    FUNC_WPDD("-PDD_WaveOutEndOfData");
}

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveOutStart
//
// Purpose: Starts (play or) processing of audio data and initiates DMAC output to the codec in response to
//          the WPDM_START message where the WAPI_INOUT directin is WAPI_OUT.
//-------------------------------------------------------------------------------------------------------------
VOID
private_WaveOutStart (
    PWAVEHDR pwh
    )
{
    FUNC_WPDD("+PDD_WaveOutStart");


    //clear the mute
    AudioOutMute(FALSE);

    //
    //fill up both pages but indicate we expect more data
    //

    v_fMoreData[WAPI_OUT] = TRUE;        // we expect to have more data coming...

    private_AudioFillBuffer(pwh, (PDWORD) dma_page[0], g_dma_buffer_size / sizeof(DWORD));
    private_AudioFillBuffer(pwh, (PDWORD) dma_page[1], g_dma_buffer_size / sizeof(DWORD));

    InitDMAC(DMA_CH_OUT);  //Load the Descriptors, Start a DMA

    FUNC_WPDD("-PDD_WaveOutStart");

}

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveOutContinue
//
// Purpose: Continues (play or) processing of audio data and DMA output to the codec in response to
//          the WPDM_CONTINUE message where the WAPI_INOUT directin is WAPI_OUT.
//-------------------------------------------------------------------------------------------------------------
VOID
private_WaveOutContinue (
    PWAVEHDR pwh
    )
{
    ULONG next_page;

    FUNC_VERBOSE("+PDD_WaveOutContinue");

    // figure out which page the DMA engine will go to next & copy there
    next_page = (v_pDMARegs->ddg[DMA_CH_OUT].ddadr == (UINT32)v_pAudioXmitA_Physical) ? 0 : 1;

    private_AudioComplete(pwh, g_dma_buffer_size);

    private_AudioFillBuffer (pwh, (PDWORD) dma_page[next_page], g_dma_buffer_size / sizeof(DWORD));


    FUNC_VERBOSE("-PDD_WaveOutContinue");
}

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveOutRestart
//
// Purpose: continues playback of paused data in response to WPDM_RESET
//-------------------------------------------------------------------------------------------------------------
MMRESULT
private_WaveOutRestart (
    PWAVEHDR pwh
    )
{
    FUNC_VERBOSE("+PDD_WaveOutRestart");

    private_WaveOutStart (pwh);

    FUNC_VERBOSE("-PDD_WaveOutRestart");
    return(MMSYSERR_NOERROR);
}



//------------------------------------------------------------------------------------------------------------
// Function: private_WaveOutPause
//
// Purpose: Pause playback of audio data in response to WPDM_PAUSE
//-------------------------------------------------------------------------------------------------------------
MMRESULT
private_WaveOutPause (
    VOID
    )
{
    FUNC_VERBOSE("+PDD_WaveOutPause");

    private_WaveOutEndOfData();

    FUNC_VERBOSE("-PDD_WaveOutPause");
    return(MMSYSERR_NOERROR);
}


//------------------------------------------------------------------------------------------------------------
// Function: private_WaveOutStop
//
// Purpose: Stop the playback of audio data in response to WPDM_STOP
//-------------------------------------------------------------------------------------------------------------
VOID
private_WaveOutStop()
{
    FUNC_WPDD("+private_WaveOutStop");

    v_fMoreData[WAPI_OUT] = FALSE;

    StopDmac(DMA_CH_OUT);

    AudioOutMute(TRUE);

    FUNC_WPDD("-private_WaveOutStop");
}
//------------------------------------------------------------------------------------------------------------
//  FUNCTION: private_AudioGetBuffer
//
//  PURPOSE: grab incoming data from DMA buffers and write it to application buffers
//------------------------------------------------------------------------------------------------------------

VOID
GetBufferM08 (PBYTE pDstBuffer, PINT16 pSrcBuffer, DWORD dwSamples)
{
    while (dwSamples-- > 0) {
        *pDstBuffer = (BYTE) BITS_16_TO_8(pSrcBuffer[0]);
        pSrcBuffer += 2;
        pDstBuffer += 1;
    }
}

VOID
GetBufferS08 (PBYTE pDstBuffer, PINT16 pSrcBuffer, DWORD dwSamples)
{
    while (dwSamples-- > 0) {
        pDstBuffer[0] = (BYTE) BITS_16_TO_8(pSrcBuffer[0]);
        pDstBuffer[1] = (BYTE) BITS_16_TO_8(pSrcBuffer[1]);
        pSrcBuffer += 2;
        pDstBuffer += 2;
    }
}


VOID
GetBufferM16 (PBYTE pDst, PINT16 pSrcBuffer, DWORD dwSamples)
{
    PINT16 pDstBuffer = (PINT16) pDst;
    while (dwSamples-- > 0) {
        pDstBuffer[0] = pSrcBuffer[0];
        pSrcBuffer += 2;
        pDstBuffer += 1;
    }
}


VOID
GetBufferS16 (PBYTE pDstBuffer, PINT16 pSrcBuffer, DWORD dwSamples)
{
    memcpy(pDstBuffer, pSrcBuffer, dwSamples * sizeof(DWORD));
}


VOID
private_AudioGetBuffer (
    PWAVEHDR pwh,
    PDWORD pSrcBuffer,
    DWORD dwSrcSamples
    )
{
    FUNC_VERBOSE("+PDD_AudioGetBuffer");

    while ((pwh != NULL) && (dwSrcSamples > 0)) {
        if (pwh->dwBytesRecorded >= pwh->dwBufferLength) {
            pwh = pwh->lpNext;
        }
        else {
            DWORD dwDstSamples = (pwh->dwBufferLength - pwh->dwBytesRecorded) / g_sample_size[WAPI_IN];
            DWORD dwSamples = min(dwSrcSamples, dwDstSamples);

            __try
            {
                g_pfnGetBuffer(pwh->lpData + pwh->dwBytesRecorded, (PINT16) pSrcBuffer, dwSamples);
            }
            __except (EXCEPTION_EXECUTE_HANDLER)
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("wavepdd: Handled buffer fault in private_AudioGetBuffer\r\n")));
            }

            pwh->dwBytesRecorded += dwSamples * g_sample_size[WAPI_IN];
            pSrcBuffer += dwSamples;
            dwSrcSamples -= dwSamples;
        }
    }

    FUNC_VERBOSE("+PDD_AudioGetBuffer");
}

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveInStart
//
// Purpose: Starts (record or) processing of audio data and initiates DMAC input from the codec in response to
//          the WPDM_START message where the WAPI_INOUT directin is WAPI_IN.
//-------------------------------------------------------------------------------------------------------------
VOID
private_WaveInStart (
    PWAVEHDR pwh
    )
{
    FUNC_WPDD("+PDD_WaveInStart");

    //clear the mute
    AudioInMute(FALSE);

    // enable microphone Boost, but keep the line from mic to speakers muted.
    ShadowWriteAC97( MIC_VOLUME, 0x8040, DEV_AUDIO);

    //
    //fill up both pages but indicate we expect more data
    //

    v_fMoreData[WAPI_IN]  = TRUE;        // we expect to have more data coming...

    InitDMAC(gInputSrc);   //Load the Descriptors, Start a DMA

    FUNC_WPDD("+PDD_WaveInStart");

}

//------------------------------------------------------------------------------------------------------------
// Function: private_WaveInContinue
//
// Purpose:  instruct the audio PDD to continue with the data pointed to by the wave header
//-------------------------------------------------------------------------------------------------------------
VOID
private_WaveInContinue(
   PWAVEHDR pwh
   )
{
    ULONG next_page;
    FUNC_VERBOSE("+PDD_WaveInContinue");

    // figure out which page the DMA engine will go to next & copy from there
    next_page = (v_pDMARegs->ddg[gInputSrc].ddadr == (UINT32) v_pAudioRcvA_Physical) ? 2 : 3;

    //fill up the input buffer (dma_page[]) pointed to by next_page
    private_AudioGetBuffer  (pwh, (PDWORD) dma_page[next_page], g_capture_buffer_size / sizeof(DWORD));

    FUNC_VERBOSE("-PDD_WaveInContinue");
}

⌨️ 快捷键说明

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