📄 waveoutpdd.cpp
字号:
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0235 );
Delay_AC();
//Audio in set up start
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0200 );
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x0000E000 );// Set Mic Volume address
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x0001C000 );// Set Record Gain address
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x0001A000 );// Set Record Select Control address
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00000400 );// Set Mic Volume data
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00004040 );// Set Record Gain data
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00000000 );// Set Record Select Control data
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0235 );
Delay_AC();
//Audio in set up end
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00082000 );
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00098000 );
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x000F8000 );
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x0008E000 );
Delay_AC();
Delay_AC();
RETAILMSG( 1, (TEXT("Master Vol =%x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_CDR )));
RETAILMSG( 1, (TEXT("PCM Vol =%x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_CDR )));
RETAILMSG( 1, (TEXT("Sample rate=%x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_CDR )));
RETAILMSG( 1, (TEXT("Mic Vol =%x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_CDR )));
//DQR_En
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0231 );
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00007800 );
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00007400 ); // DRQ Enable
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CDR, (ULONG)0x00007800 );
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x00007400 ); // DRQ Enable
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_FSR, 0x0000 );
Delay_AC();
WRITE_REGISTER_USHORT((PUSHORT)pCODEC_CR, 0x0235 );
Delay_AC();
Delay_AC();
WRITE_REGISTER_ULONG((PULONG)pCODEC_CAR, (ULONG)0x000f4000 ); // Serial Configration
Delay_AC();
RETAILMSG( 1, (TEXT("Serial Configration =%08x\r\n"), (ULONG)READ_REGISTER_ULONG((PULONG)pCODEC_CDR )));
// Set default volume to maximum
v_nVolume = 0xFFFFFFFF;
// Initialize AudioOutInterrupt Flag
/* pDriverGlobals->aud.play_address = (ULONG)NULL;
pDriverGlobals->aud.outInt = (USHORT)NULL;
*/ pDmaOutObject->SetGlobalPlayAddress(NULL);
pDmaOutObject->ResetGlobalOutInt(FALSE);
RETAILMSG(1, (TEXT("PDD_AudioOutInitialize: Successful Init\r\n")));
RETAILMSG(1, (TEXT("WaveOutpdd.c private_AudioOutInitialize: END\r\n")));
FUNC("-PDD_AudioOutInitialize");
return TRUE;
}
/*****************************************************************************
* FUNCTION : private_AudioOutPowerHandler
* DESCRIPTION : performs power on/off
* INPUTS : bPowerDown 1=power off, 0=power on
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_AudioOutPowerHandler(
BOOL bPowerDown
)
{
BOOL Success;
FUNC("private_AudioOutPowerHandler");
DEBUGMSG(ZONE_TEST, (TEXT("private_AudioOutPowerHandler ---- bPowerDown=%d\r\n"),bPowerDown));
if( bPowerDown )
{
private_AudioOutDeinitialize();
}
else
{ // power up
Success=private_AudioOutInitialize();
}
return; // (see also private_WaveOutClose)
}
/*****************************************************************************
* FUNCTION : private_AudioOutDeinitialize
* DESCRIPTION : Reset playback device to initial state
* INPUTS : None
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_AudioOutDeinitialize(
VOID
)
{
FUNC("+PDD_AudioOutDeinitialize");
/* if( pDMAC_RegBase )
VirtualFree((PVOID)pDMAC_RegBase, 0, MEM_RELEASE);
if( pINTC_Area_1_RegBase )
VirtualFree((PVOID)pINTC_Area_1_RegBase, 0, MEM_RELEASE);
if( pINTC_Area_7_RegBase )
VirtualFree((PVOID)pINTC_Area_7_RegBase, 0, MEM_RELEASE);
*/
if( pCC_CODEC_RegBase )
VirtualFree((PVOID)pCC_CODEC_RegBase, 0, MEM_RELEASE);
if( pCC_SYS_RegBase )
VirtualFree((PVOID)pCC_SYS_RegBase, 0, MEM_RELEASE);
if( pAudioBufferBase )
VirtualFree((PVOID)pAudioBufferBase, 0, MEM_RELEASE);
if (pDmaOutObject) {
delete pDmaOutObject;
pDmaOutObject=NULL;
}
/* if( pDriverGlobals )
VirtualFree((PVOID)pDriverGlobals, 0, MEM_RELEASE);
*/
FUNC("-PDD_AudioOutDeinitialize");
}
/*****************************************************************************
* FUNCTION : private_WaveOutStart
* DESCRIPTION : Initiates playback of wave
* INPUTS : wave
* OUTPUTS : None
* DESIGN NOTES : puts double buffer in initial state, starts play
* CAUTIONS :
*****************************************************************************/
VOID
private_WaveOutStart (
PWAVEHDR pwh
)
{
const PPCMWAVEFORMAT pFormat = (PPCMWAVEFORMAT) g_pwfx[WAPI_OUT];
FUNC_WPDD("+PDD_WaveOutStart");
v_fMoreData[WAPI_OUT] = TRUE; // more data expected
v_nNextPage = 0;
private_AudioFillBuffer (pwh); // [v_nNextPage = 0]
private_AudioFillBuffer (pwh); // [v_nNextPage = 1]
//RX TX Valid Slot
WRITE_REGISTER_ULONG((PULONG)pCODEC_ATAGR, 0x00001ff8 );
private_AudioPlayFirstBuffer(); // start playback
FUNC_WPDD("-PDD_WaveOutStart");
}
/*****************************************************************************
* FUNCTION : private_AudioFillBuffer
* DESCRIPTION : fills next buffer from given wave
* toggles ready/empty pointers to double buffer
* INPUTS : wave
* OUTPUTS : None
* DESIGN NOTES :
* CAUTIONS :
*****************************************************************************/
VOID
private_AudioFillBuffer (
PWAVEHDR pwh
)
{
const PPCMWAVEFORMAT pFormat = (PPCMWAVEFORMAT) g_pwfx[WAPI_OUT];
unsigned int i,j;
LONG samplingRate;
ULONG l_sample = 0;
ULONG r_sample = 0;
UCHAR l_wksample = 0;
UCHAR r_wksample = 0;
INT32 multiplier, log2ofDivisor;
PCM_SAMPLE pcmsample;
ULONG nVolume = v_nVolume & 0xFFFF;
PPCM_SAMPLE pSampleSource;
ULONG *lpAudioBufferBase;
unsigned int extend_data_count;
unsigned int data_write_count;
unsigned int loop_count;
FUNC_VERBOSE("+PDD_AudioFillBuffer");
i = (nVolume >> 12) & 0x0F; // prepare parameters
multiplier = VOL[i].multiplier; // for table-driven
log2ofDivisor = VOL[i].divisor; // scaling of volume
//Set terminal condition for double-buffer and exit if no data remains
if (pwh == NULL)
{
//pDriverGlobals->aud.play_address = (ULONG)NULL;
pDmaOutObject->SetGlobalPlayAddress(NULL);
return;
}
//
// For this line, the number of bytes from this audio stream
// depends on the dma_buffer_size and the sample rate of the stream
//
// What's the maximum number of samples from this stream are needed
// to fill the DMA buffer?
//
samplingRate = pFormat->wf.nSamplesPerSec;
lpAudioBufferBase = (ULONG *)(pAudioBufferBase + v_nNextPage * pDmaOutObject->GetAudioDmaPageSize()/*AUDIO_DMA_PAGE_SIZE*/);
extend_data_count = 0;
data_write_count = 0;
loop_count = 0;
//
// For each sample in the buffer...
//
for (i = 0; i < pDmaOutObject->GetAudioDmaPageSize()/*AUDIO_DMA_PAGE_SIZE*/ / 4 ; )
{
if (pwh != NULL && pwh->dwBytesRecorded >= pwh->dwBufferLength)
{
pwh = pwh->lpNext;
}
if (pwh == NULL)
{
l_sample = 0;
r_sample = l_sample;
}
else
{
pSampleSource = (PPCM_SAMPLE) (pwh->lpData + pwh->dwBytesRecorded);
switch (g_pcmtype[WAPI_OUT])
{
case PCM_TYPE_M8:
l_sample = (INT16) pSampleSource->m8.sample;
pwh->dwBytesRecorded++;
l_sample = l_sample -128;
l_sample = l_sample << 12;
r_sample = l_sample;
break;
case PCM_TYPE_S8:
pcmsample.s8.sample_left = pSampleSource->s8.sample_left;
pcmsample.s8.sample_right = pSampleSource->s8.sample_right;
pwh->dwBytesRecorded += 2;
l_sample = pcmsample.s8.sample_left;
r_sample = pcmsample.s8.sample_right;
l_sample = l_sample -128;
l_sample = l_sample << 12;
r_sample = r_sample -128;
r_sample = r_sample << 12;
break;
case PCM_TYPE_M16:
l_sample = pSampleSource->m16.sample;
pwh->dwBytesRecorded += 2;
l_sample = l_sample << 4;
r_sample = l_sample;
break;
case PCM_TYPE_S16:
pcmsample.s16.sample_left = pSampleSource->s16.sample_left;
pcmsample.s16.sample_right = pSampleSource->s16.sample_right;
pwh->dwBytesRecorded += 4;
l_sample = pcmsample.s16.sample_left;
r_sample = pcmsample.s16.sample_right;
l_sample = l_sample << 4;
r_sample = r_sample << 4;
break;
} // end switch
l_sample = ((l_sample * multiplier) >> log2ofDivisor);
r_sample = ((r_sample * multiplier) >> log2ofDivisor);
} // endif
l_sample = ( l_sample & 0x000fffff );
r_sample = ( r_sample & 0x000fffff );
switch( (ULONG)samplingRate )
{
case 11025:
loop_count = 4;
break;
case 22050:
loop_count = 2;
break;
case 44100:
loop_count = 1;
break;
default:
RETAILMSG(1, (TEXT("ERROR! SamplingRate\r\n")));
break;
}
for(j=0;j<loop_count;j++ ){
*(lpAudioBufferBase + i ) = l_sample;
*(lpAudioBufferBase + i + 1) = r_sample;
i = i + 2;
data_write_count = data_write_count + 1;
if ( (( extend_data_count + 1 ) * 11.30645969) < data_write_count ) {
*(lpAudioBufferBase + i ) = l_sample;
*(lpAudioBufferBase + i + 1) = r_sample;
i = i + 2;
extend_data_count = extend_data_count + 1;
}
}
} // for i each sample
// Point AudioPlayingAddress to buffer just filled; toggle v_nNextPage
// pDriverGlobals->aud.play_address = (ULONG)dma_pagePhysicalAddress[v_nNextPage];
pDmaOutObject->SetGlobalAddr(v_nNextPage==0);
v_nNextPage = 1 - v_nNextPage;
FUNC_VERBOSE("-PDD_AudioFillBuffer");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -