📄 wavepdd.c
字号:
//
// Grab a spinlock
//
InitializeCriticalSection(&WaveDevice->CriticalSection);
if(!InitializePlatform(WaveDevice)) {
DEBUGMSG(ZONE_PDD,(L"Failed to Initialize platform registers\r\n"));
goto ErrorReturn;
}
if(!InitializeDMA(WaveDevice)) {
DEBUGMSG(ZONE_PDD,(L"Failed to Initialize DMA\r\n"));
goto ErrorReturn;
}
if(!InitializeInterrupt(WaveDevice)) {
DEBUGMSG(ZONE_PDD,(L"Failed to Initialize Interrupt\r\n"));
goto ErrorReturn;
}
WaveOutResource = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
sizeof(*WaveOutResource));
if(WaveOutResource==NULL) {
DEBUGMSG(ZONE_PDD,(L"Failed to allocate Out Resouece\r\n"));
goto ErrorReturn;
}
WaveOutResource->WaveDirection=WAPI_OUT;
WaveOutResource->DmaBufferSize=WaveDevice->DmaBufferSize;
WaveOutResource->DMAChannel=WaveDevice->DMAChannelOutput;
WaveOutResource->pI2S=WaveDevice->pI2S;
WaveOutResource->CriticalSection=WaveDevice->CriticalSection;
WaveInResource = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
sizeof(*WaveInResource));
if(WaveInResource==NULL) {
DEBUGMSG(ZONE_PDD,(L"Failed to allocate Out Resource\r\n"));
goto ErrorReturn;
}
WaveInResource->WaveDirection=WAPI_IN;
WaveInResource->DmaBufferSize=WaveDevice->DmaBufferSize;
WaveInResource->DMAChannel=WaveDevice->DMAChannelInput;
WaveInResource->pI2S=WaveDevice->pI2S;
WaveInResource->CriticalSection=WaveDevice->CriticalSection;
DEBUGMSG(ZONE_PDD,(L"-PDD_AudioInitialize\r\n"));
return TRUE;
ErrorReturn:
DEBUGMSG(ZONE_PDD,(L"-PDD_AudioInitialize failed\r\n"));
return FALSE;
}
VOID
PDD_AudioDeinitialize (
VOID
)
{
DEBUGMSG(ZONE_PDD, (TEXT("+Audio PDD_AudioDeinitialize.\r\n")));
// FIXME FIXME need to free used resources
if (WaveDevice != NULL) {
LocalFree(WaveDevice);
WaveDevice = NULL;
}
DEBUGMSG(ZONE_PDD, (TEXT("-Audio PDD_AudioDeinitialize.\r\n")));
return;
}
VOID
PDD_AudioPowerHandler (
BOOL PowerDown
)
{
if(PowerDown==TRUE) {
ShutdownDma(WaveInResource);
ShutdownDma(WaveOutResource);
WaveInResource->DmaRunning = FALSE;
WaveOutResource->DmaRunning = FALSE;
// Halt the I2S
WRITE_REGISTER_ULONG((PULONG)&WaveDevice->pI2S->psc.ctl,0);
} else {
WaveDevice->InPowerHandler=TRUE;
InitializeRegisters(WaveDevice->pI2S);
WaveInResource->DmaRunning = FALSE;
WaveOutResource->DmaRunning = FALSE;
WaveDevice->InPowerHandler=FALSE;
}
return;
}
MMRESULT
PDD_WaveProc(
IN WAPI_INOUT ApiDirection,
IN ULONG Code,
IN OUT ULONG Param1,
IN OUT ULONG Param2
)
/*++
Routine Description:
This routine is called to access various other functions in the driver
It's similar to an I/O control in standard streams drivers.
Arguments:
ApiDirection - Direction (input or output).
Code - Code specifying which function to call.
Param1 - Parameter 1. Its usage is dependent on which function is called.
Param2 - Parameter 2. Its usage is dependent on which function is called.
Return Value:
None.
--*/
{
MMRESULT ReturnValue;
DEBUGMSG(ZONE_PDD, (TEXT("+Audio PDD_WaveProc.\r\n")));
ReturnValue = MMSYSERR_NOERROR;
switch(Code) {
case WPDM_CLOSE:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_CLOSE(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
ReturnValue = WaveClose(WaveInResource);
}
else {
ReturnValue = WaveClose(WaveOutResource);
}
break;
case WPDM_CONTINUE:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_CONTINUE(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
WaveInContinue(WaveInResource,
(PWAVEHDR)Param1);
}
else {
WaveOutContinue(WaveOutResource,
(PWAVEHDR)Param1);
}
break;
case WPDM_GETDEVCAPS:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_GETDEVCAPS(%s).\r\n"),
DIR_STR(ApiDirection)));
ReturnValue = WaveGetDeviceCapabilities(ApiDirection,
(PVOID)Param1,
(UINT)Param2);
break;
case WPDM_OPEN:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_OPEN(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
ReturnValue = WaveOpen((LPWAVEFORMATEX)Param1,
(BOOL)Param2,
WaveInResource);
}
else {
ReturnValue = WaveOpen((LPWAVEFORMATEX)Param1,
(BOOL)Param2,
WaveOutResource);
}
break;
case WPDM_STANDBY:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_STANDBY(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
WaveStandby(WaveInResource);
}
else {
WaveStandby(WaveOutResource);
}
break;
case WPDM_START:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_START(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
WaveInStart(WaveInResource,
(PWAVEHDR)Param1);
}
else {
WaveOutStart(WaveOutResource,
(PWAVEHDR)Param1);
}
break;
case WPDM_STOP:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_STOP(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
WaveInStop(WaveInResource);
}
else {
WaveOutEndOfData(WaveOutResource);
}
break;
case WPDM_PAUSE:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_PAUSE(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_OUT) {
//
// Call end of data to halt transfer.
//
WaveOutEndOfData(WaveOutResource);
}
else {
ReturnValue = MMSYSERR_NOTSUPPORTED;
}
break;
case WPDM_ENDOFDATA:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_ENDOFDATA(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_OUT) {
WaveOutEndOfData(WaveOutResource);
}
else {
ReturnValue = MMSYSERR_NOTSUPPORTED;
}
break;
case WPDM_RESTART:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_RESTART(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_OUT) {
//
// Call start to continue in stream where we left off.
//
WaveOutStart(WaveOutResource,
(PWAVEHDR)Param1);
}
else {
ReturnValue = MMSYSERR_NOTSUPPORTED;
}
break;
case WPDM_GETVOLUME:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: WPDM_GETVOLUME.\r\n")));
ReturnValue = GetOutputVolume(WaveDevice,
(PULONG)Param1);
break;
case WPDM_SETVOLUME:
ReturnValue = SetOutputVolume(WaveDevice,
Param1);
break;
default:
DEBUGMSG(ZONE_PDD, (
TEXT(" PDD_WaveProc: Unknown code %u.\r\n"),
Code));
ReturnValue = MMSYSERR_NOTSUPPORTED;
break;
}
DEBUGMSG(ZONE_PDD, (TEXT("-Audio PDD_WaveProc.\r\n")));
return ReturnValue;
}
AUDIO_STATE
PDD_AudioGetInterruptType(
VOID
)
{
AUDIO_STATE PendingInterrupts;
ULONG Mask;
PendingInterrupts = 0;
DEBUGMSG(ZONE_PDD, (TEXT("+Audio PDD_AudioGetInterruptType.\r\n")));
//
// For each of input and output, read the DMA status registers to see if
// there is a pending interrupt. Depending on whether or not there is a
// pending interrupt and if there is more data to play/record, various
// flags are ORed into the audio state to be returned to the MDD.
//
Mask = HalCheckForDMAInterrupt(WaveDevice->DMAChannelInput);
if( Mask )
{
if( WaveInResource->MoreData )
{
DEBUGMSG(DMA_VERBOSE_DEBUG, (
TEXT("PDD_AudioGetInterruptType: %s more data.\r\n"),
DIR_STR(WAPI_IN)));
PendingInterrupts |= AUDIO_STATE_IN_RECORDING;
}
else
{
DEBUGMSG(ZONE_PDD, (
TEXT("PDD_AudioGetInterruptType: %s stopped.\r\n"),
DIR_STR(WAPI_IN)));
PendingInterrupts |= AUDIO_STATE_IN_STOPPED;
SetEvent(hAudioInterrupt);
}
HalAckDMAInterrupt(WaveDevice->DMAChannelInput,Mask);
goto ReturnWaveStatus;
}
//
// Wave output.
//
Mask = HalCheckForDMAInterrupt(WaveDevice->DMAChannelOutput);
if (Mask)
{
if (WaveOutResource->MoreData)
{
PendingInterrupts |= AUDIO_STATE_OUT_PLAYING;
}
else
{
PendingInterrupts |= AUDIO_STATE_OUT_STOPPED;
}
HalAckDMAInterrupt(WaveDevice->DMAChannelOutput,Mask);
}
ReturnWaveStatus:
DEBUGMSG(ZONE_PDD, (TEXT("-Audio PDD_AudioGetInterruptType.\r\n")));
return PendingInterrupts;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -