📄 wavepdd.c
字号:
//------------------------------------------------------------------------------------------------------------
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 + -