📄 audio.c
字号:
//
// Map in DMA channel registers.
//
PhysAddr.QuadPart = AHB_DMA_CTL_REGS_BASE;
WaveDevice->AHBDmaCtrlRegPtr = MmMapIoSpace(PhysAddr,
sizeof(AHB_DMA_CTL_REGS),
FALSE);
if (WaveDevice->AHBDmaCtrlRegPtr == NULL) {
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: Unable to map DMA regs.\r\n")));
goto ErrorReturn;
}
WaveDevice->DmaCtrlInput = &WaveDevice->AHBDmaCtrlRegPtr->AAC0_Rx;
WaveDevice->DmaCtrlOutput = &WaveDevice->AHBDmaCtrlRegPtr->AAC0_Tx;
//
// Set up platform specific registers.
//
Success = InitializePlatformRegisters(WaveDevice);
if (Success == FALSE) {
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: Failed to init platform regs\r\n")));
SetLastError(ERROR_GEN_FAILURE);
goto ErrorReturn;
}
//
// Set up the AAC registers.
//
Success = InitializeAacRegisters(WaveDevice);
if (Success == FALSE) {
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: Failed to init AAC regs.\r\n")));
SetLastError(ERROR_GEN_FAILURE);
goto ErrorReturn;
}
//
// Initialize the codec.
//
Success = CodecInitialize(WaveDevice);
if (Success == FALSE) {
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: Failed codec init.\r\n")));
goto ErrorReturn;
}
//
// Allocate and initialize DMA resources.
//
Success = InitializeDmaResources(WaveDevice);
if (Success == FALSE) {
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: Failed DMA resources init.\r\n")));
goto ErrorReturn;
}
//
// Initialize interrupts.
//
Success = InitializeInterruptHandling(WaveDevice);
if (Success == FALSE) {
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: Failed interrupts init.\r\n")));
goto ErrorReturn;
}
//
// Allocate and initialize data structures to track resources used for
// the input and output streams.
//
WaveInResource = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
sizeof(*WaveInResource));
if (WaveInResource == NULL) {
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: Failed to allocate input structure\r\n")));
goto ErrorReturn;
}
WaveOutResource = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
sizeof(*WaveOutResource));
if (WaveInResource == NULL) {
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: Failed to allocate output structure\r\n")));
goto ErrorReturn;
}
BufferOffset = WaveDevice->DmaBufferSize / sizeof(ULONG);
WaveInResource->SysIntr = WaveDevice->SysIntrInput;
WaveInResource->WaveDirection = WAPI_IN;
WaveInResource->ABPClkCtrlRegPrt = WaveDevice->ABPClkCtrlRegPrt;
WaveInResource->AacRegPtr = WaveDevice->AacRegPtr;
WaveInResource->AHBDmaCtrlRegPtr = WaveDevice->AHBDmaCtrlRegPtr;
WaveInResource->DmaRegPtr = WaveDevice->DmaCtrlInput;
WaveInResource->DmaBufferSize = WaveDevice->DmaBufferSize;
WaveInResource->AdapterObject = WaveDevice->AdapterObjectInput;
WaveInResource->MapRegsBase = WaveDevice->MapRegsBaseInput;
WaveInResource->DmaBufferMdl = WaveDevice->DmaBuffersMdl;
WaveInResource->DmaBufferA = WaveDevice->DmaBuffersBase;
WaveInResource->DmaBufferB = WaveDevice->DmaBuffersBase + BufferOffset;
WaveOutResource->SysIntr = WaveDevice->SysIntrOutput;
WaveOutResource->WaveDirection = WAPI_OUT;
WaveOutResource->ABPClkCtrlRegPrt = WaveDevice->ABPClkCtrlRegPrt;
WaveOutResource->AacRegPtr = WaveDevice->AacRegPtr;
WaveOutResource->AHBDmaCtrlRegPtr = WaveDevice->AHBDmaCtrlRegPtr;
WaveOutResource->DmaRegPtr = WaveDevice->DmaCtrlOutput;
WaveOutResource->DmaBufferSize = WaveDevice->DmaBufferSize;
WaveOutResource->AdapterObject = WaveDevice->AdapterObjectOutput;
WaveOutResource->MapRegsBase = WaveDevice->MapRegsBaseOutput;
WaveOutResource->DmaBufferMdl = WaveDevice->DmaBuffersMdl;
WaveOutResource->DmaBufferA = WaveDevice->DmaBuffersBase + (2 * BufferOffset);
WaveOutResource->DmaBufferB = WaveDevice->DmaBuffersBase + (3 * BufferOffset);
DEBUGMSG(1, (TEXT("PDD_AudioInitialize: DmaBuffersBase=0x%x DmaBufferA=0x%x DmaBufferB=0x%x\r\n"),
WaveDevice->DmaBuffersBase,
WaveOutResource->DmaBufferA,
WaveOutResource->DmaBufferB));
DEBUGMSG(1, (TEXT("Audio: Audio system initialized\r\n")));
RoutineSuccess = TRUE;
ErrorReturn:
if (RoutineSuccess == FALSE) {
RETAILMSG(1, (TEXT("Audio: Audio system initialization error\r\n")));
PDD_AudioDeinitialize();
}
return RoutineSuccess;
}
VOID
PDD_AudioDeinitialize (
VOID
)
{
if (WaveDevice != NULL) {
DeleteCriticalSection(&WaveDevice->Cs);
LocalFree(WaveDevice);
WaveDevice = NULL;
DEBUGMSG(1,(TEXT("Deinitializing Audio.\r\n")));
}
return;
}
VOID
PDD_AudioPowerHandler (
BOOL PowerDown
)
{
#if 0
PCODEC_DEVICE CodecDevice;
ULONG TempVal;
APB_AAC_REGS* AacRegPtr = WaveOutResource->AacRegPtr;
CodecDevice = WaveDevice->CodecDevice;
if (PowerDown) {
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler:Power Down\r\n")));
TempVal = 0x0100;
if (AAC_WriteCODECIndexRegister_Pmgt (AacRegPtr, AC97_POWER_CONTROL, TempVal)) {
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler: Set Power down Control failed-1\r\n")));
}
TempVal = 0x0300;
if (AAC_WriteCODECIndexRegister_Pmgt (AacRegPtr, AC97_POWER_CONTROL, TempVal)) {
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler: Set Power down Control failed-2\r\n")));
}
TempVal = 0x8300;
if (AAC_WriteCODECIndexRegister_Pmgt (AacRegPtr, AC97_POWER_CONTROL, TempVal)) {
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler: Set Power down Control failed-2\r\n")));
}
}
else {
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler:Power Up\r\n")));
TempVal = 0x0300;
if (AAC_WriteCODECIndexRegister_Pmgt (AacRegPtr, AC97_POWER_CONTROL, TempVal)) {
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler: Set Power up Control failed\r\n")));
}
TempVal = 0x0100;
if (AAC_WriteCODECIndexRegister_Pmgt (AacRegPtr, AC97_POWER_CONTROL, TempVal)) {
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler: Set Power up Control failed\r\n")));
}
TempVal = 0x0000;
if (AAC_WriteCODECIndexRegister_Pmgt (AacRegPtr, AC97_POWER_CONTROL, TempVal)) {
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler: Set Power up Control failed\r\n")));
}
}
#else
DEBUGMSG(1, (TEXT("PDD_AudioPowerHandler: Not used\r\n")));
#endif
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;
ReturnValue = MMSYSERR_NOERROR;
EnterCriticalSection(&WaveDevice->Cs);
switch(Code) {
case WPDM_CLOSE:
DEBUGMSG(1, (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(1, (TEXT("PDD_WaveProc: WPDM_CONTINUE(%s).\r\n"), DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
WaveInContinue(WaveInResource, WaveOutResource, (PWAVEHDR)Param1);
}
else {
WaveOutContinue(WaveOutResource, (PWAVEHDR)Param1);
}
break;
case WPDM_GETDEVCAPS:
DEBUGMSG(1, (TEXT("PDD_WaveProc: WPDM_GETDEVCAPS(%s).\r\n"), DIR_STR(ApiDirection)));
ReturnValue = WaveGetDeviceCapabilities(ApiDirection,
(PVOID)Param1,
(UINT)Param2);
break;
case WPDM_OPEN:
DEBUGMSG(1, (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(1, (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(1, (TEXT("PDD_WaveProc: WPDM_START(%s).\r\n"), DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
WaveInStart(WaveInResource, WaveOutResource,
(PWAVEHDR)Param1);
}
else {
WaveOutStart(WaveOutResource,
(PWAVEHDR)Param1);
}
break;
case WPDM_STOP:
DEBUGMSG(1, (TEXT("PDD_WaveProc: WPDM_STOP(%s).\r\n"),
DIR_STR(ApiDirection)));
if (ApiDirection == WAPI_IN) {
WaveInStop(WaveInResource, WaveOutResource);
}
else {
WaveOutEndOfData(WaveOutResource);
}
break;
case WPDM_PAUSE:
DEBUGMSG(1, (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(1, (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(1, (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(1, (TEXT("PDD_WaveProc: WPDM_GETVOLUME.\r\n")));
ReturnValue = GetOutputVolume(WaveDevice, (PULONG) Param1);
break;
case WPDM_SETVOLUME:
DEBUGMSG(1, (TEXT("PDD_WaveProc: WPDM_SETVOLUME (0x%x)\r\n"),Param1));
ReturnValue = SetOutputVolume(WaveDevice, Param1);
DEBUGMSG(1, (TEXT("PDD_WaveProc: WPDM_SETVOLUME done\r\n")));
break;
default:
DEBUGMSG(1, (TEXT("PDD_WaveProc: Unknown code %u.\r\n"), Code));
ReturnValue = MMSYSERR_NOTSUPPORTED;
break;
}
LeaveCriticalSection(&WaveDevice->Cs);
return ReturnValue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -