📄 audio.c
字号:
static
BOOLEAN
InitializeInterruptHandling(
IN OUT PWAVE_DEVICE_INSTANCE WaveDevice
)
{
BOOLEAN RoutineSuccess;
BOOL Success;
ULONG SysIntr;
INTR_MODE IntrMode;
ULONG Vector;
ULONG BusNumber;
DEBUGMSG(1, (TEXT("InitializeInterruptHandling:\r\n")));
RoutineSuccess = FALSE;
IntrMode = INTR_MODE_LEVEL | INTR_MODE_POSITIVE_LOGIC;
//
// Allocate a SYSINTR for output.
//
Vector = HWINT_DMA_AAC0_TX;
BusNumber = CHIP_INTERNAL_BUS;
SysIntr = InterruptConnect(Internal,
BusNumber,
Vector,
IntrMode);
DEBUGMSG(1, (TEXT("InitializeInterruptHandling: output Vector=0x%x SysIntr=0x%x\r\n"),
Vector,SysIntr));
if (SysIntr == SYSINTR_NOP) {
DEBUGMSG(1, (TEXT("InitializeInterruptHandling: Failed SYSINTR allocation for output\r\n")));
goto ErrorReturn;
}
WaveDevice->SysIntrOutput = SysIntr;
//
// Save SysIntr for use in the MDD InterruptInitialize().
//
gIntrAudio = WaveDevice->SysIntrOutput;
//
// Allocate a SYSINTR for input.
//
Vector = HWINT_DMA_AAC0_RX;
SysIntr = InterruptConnect(Internal,
BusNumber,
Vector,
IntrMode);
DEBUGMSG(1, (TEXT("InitializeInterruptHandling: input Vector=0x%x SysIntr=0x%x\r\n"),
Vector,SysIntr));
if (SysIntr == SYSINTR_NOP) {
DEBUGMSG(1, (TEXT("InitializeInterruptHandling: Failed SYSINTR allocation for input\r\n")));
goto ErrorReturn;
}
WaveDevice->SysIntrInput = SysIntr;
//
// Associate the SYSINTRs with the audio interrupt event in the MDD.
//
Success = InterruptInitialize(WaveDevice->SysIntrInput,
hAudioInterrupt,
NULL,
0);
if (Success == FALSE) {
DEBUGMSG(1, (TEXT("InitializeInterruptHandling: Failed to initialize input interrupt\r\n")));
goto ErrorReturn;
}
WaveDevice->SysIntrInputInitialized = TRUE;
//
// Note:
// MDD WMDD_Init() makes the following call to initialize audio interrupt:
//
// if (! InterruptInitialize(gIntrAudio, hAudioInterrupt, NULL, 0)) {
// DEBUGMSG(ZONE_ERROR, (TEXT("WMDD_Init - InterruptInitialize(%d,%08x) Failed\r\n"), gIntrAudio, hAudioInterrupt));
// goto InitFail;
// }
//
// MDD use one audio interrupt for both wave in and wave out. This is incompatible with
// the structure of the this driver. Only the wave out will work. A complete rewrite is
// needed to support both wave in and wave out.
//
// Comment out the following InterruptInitialize() call because it is done in the MDD for
// wave out.
//
#if 0
Success = InterruptInitialize(WaveDevice->SysIntrOutput,
hAudioInterrupt,
NULL,
0);
if (Success == FALSE) {
DEBUGMSG(1, (
TEXT("InitializeInterruptHandling: Failed to initialize")
TEXT(" output interrupt.\r\n")));
goto ErrorReturn;
}
#endif
WaveDevice->SysIntrOutputInitialized = TRUE;
DEBUGMSG(1, (TEXT("InitializeInterruptHandling: success\r\n")));
RoutineSuccess = TRUE;
ErrorReturn:
return RoutineSuccess;
}
static
MMRESULT
WaveGetDeviceCapabilities(
IN WAPI_INOUT ApiDirection,
OUT PVOID DeviceCapabilities,
IN UINT Size
)
/*++
Routine Description:
Called to determine audio device capabilities.
Arguments:
ApiDirection - Audio direction (input or output).
DeviceCapabilites - Pointer to device capabilities structure or NULL.
Size - Size of device capabilities structure.
Return Value:
Returns the appropriate MMSYSERR condition code.
--*/
{
MMRESULT ReturnValue;
PWAVEINCAPS InputCapabilities;
PWAVEOUTCAPS OutputCapabilities;
DEBUGMSG(1, (TEXT("WaveGetDeviceCapabilities:\r\n")));
ReturnValue = MMSYSERR_NOTSUPPORTED;
InputCapabilities = DeviceCapabilities;
OutputCapabilities = DeviceCapabilities;
//
// If DeviceCapabilities is NULL, we are asking if the driver PDD is
// capable of this mode at all. In other words, if the API direction is
// input, we return no MMSYSERR_NOERROR if input is supported, and
// MMSYSERR_NOTSUPPORTED otherwise.
//
if (DeviceCapabilities == NULL) {
if (ApiDirection == WAPI_OUT) {
ReturnValue = MMSYSERR_NOERROR;
}else
ReturnValue = MMSYSERR_NOERROR;
goto ErrorReturn;
}
//
// Fill in the device capabilities structure here. Note that the input
// and output capabilities structure is identical except for the the
// dwSupport field which is present in the output structure but absent in
// the input structure.
//
if (ApiDirection == WAPI_OUT) {
OutputCapabilities->wMid = MM_MICROSOFT;
OutputCapabilities->wPid = MM_MSFT_GENERIC_WAVEOUT;
OutputCapabilities->vDriverVersion = MAKEWORD(0, 1); // v1.0
_stprintf(OutputCapabilities->szPname, TEXT("BSQUARE: CS4201"));
//
// 11.025 kHz, 22.05 kHz, 44.1 kHz, mono and stereo, 8-bit and
// 16-bit, all combinations thereof.
//
// Note that 8 kHz is also supported, but not listed here.
//
OutputCapabilities->dwFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_1M16 |
WAVE_FORMAT_1S08 | WAVE_FORMAT_1S16 |
WAVE_FORMAT_2M08 | WAVE_FORMAT_2M16 |
WAVE_FORMAT_2S08 | WAVE_FORMAT_2S16 |
WAVE_FORMAT_4M08 | WAVE_FORMAT_4M16 |
WAVE_FORMAT_4S08 | WAVE_FORMAT_4S16;
OutputCapabilities->wChannels = 2;
OutputCapabilities->dwSupport = WAVECAPS_VOLUME;
}
else {
InputCapabilities->wMid = MM_MICROSOFT;
InputCapabilities->wPid = MM_MSFT_GENERIC_WAVEIN;
InputCapabilities->vDriverVersion = MAKEWORD(0, 1); // v1.0
_stprintf(InputCapabilities->szPname, TEXT("BSQUARE: CS4201"));
//
// 11.025 kHz, 22.05 kHz, 44.1 kHz, Monoaural and Stereo, 8-bit and
// 16-bit, all combinations thereof.
//
InputCapabilities->dwFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_1M16 |
WAVE_FORMAT_1S08 | WAVE_FORMAT_1S16 |
WAVE_FORMAT_2M08 | WAVE_FORMAT_2M16 |
WAVE_FORMAT_2S08 | WAVE_FORMAT_2S16 |
WAVE_FORMAT_4M08 | WAVE_FORMAT_4M16 |
WAVE_FORMAT_4S08 | WAVE_FORMAT_4S16;
InputCapabilities->wChannels = 2;
}
ReturnValue = MMSYSERR_NOERROR;
ErrorReturn:
return ReturnValue;
}
static
MMRESULT
WaveOpen(
IN LPWAVEFORMATEX WaveFormat,
IN BOOL QueryFormatOnly,
IN OUT PWAVE_RESOURCE WaveResource
)
/*++
Routine Description:
Opens the specified stream or returns information about valid stream
formats.
Arguments:
WaveFormat - Pointer to stream format description.
QueryFormatOnly - Flag for querying device only.
WaveResource - Pointer to the wave stream resource structure to update.
Return Value:
Returns the appropriate MMSYSERR condition code.
--*/
{
MMRESULT ReturnValue;
LONG OldValue;
APB_AAC_REGS* AacRegPtr = WaveResource->AacRegPtr;
#ifdef NOAUDIODMA
DEBUGMSG(1, (TEXT("WaveOpen: Using Polling\r\n")));
#else
DEBUGMSG(1, (TEXT("WaveOpen: Using DMA\r\n")));
#endif
ReturnValue = MMSYSERR_ERROR;
//
// Verify that a valid stream is being opened by checking the format
// parameters. If any of the parameters indicate an unsupported stream
// type, return an error.
//
//
// Wave stream format. Only PCM is supported.
//
if (WaveFormat->wFormatTag != WAVE_FORMAT_PCM) {
DEBUGMSG(1, (TEXT("WaveOpen: Only WAVE_FORMAT_PCM is supported.\r\n")));
ReturnValue = WAVERR_BADFORMAT;
goto ErrorReturn;
}
//
// Number of channels. Only 1 (mono) or 2 (stereo) are supported.
//
if (WaveFormat->nChannels != 1 &&
WaveFormat->nChannels != 2) {
DEBUGMSG(1, (TEXT("WaveOpen: Only 1 or 2 channels is supported.\r\n")));
ReturnValue = WAVERR_BADFORMAT;
goto ErrorReturn;
}
//
// Sampling frequency. Only 8000, 11025, 22050, and 44100 Hz sample
// rates are supported. Note that the 8000 Hz rate is not listed as a
// supported sample rate in WaveGetDeviceCapabilities because there are
// no defines for that sample rate. Nevertheless, 8 khz is a popular
// sampling rate and is thus supported.
//
if (WaveFormat->nSamplesPerSec != 8000 &&
WaveFormat->nSamplesPerSec != 11025 &&
WaveFormat->nSamplesPerSec != 22050 &&
WaveFormat->nSamplesPerSec != 44100) {
DEBUGMSG(1, (TEXT("WaveOpen: Only 8.0, 11.025, 22.05, and 44.1 kHz are supported\r\n")));
ReturnValue = WAVERR_BADFORMAT;
goto ErrorReturn;
}
//
// Number of bits per sample. Only 8-bit (signed) and 16-bit (unsigned)
// are supported.
//
if (WaveFormat->wBitsPerSample != 8 &&
WaveFormat->wBitsPerSample != 16) {
DEBUGMSG(1, (TEXT("WaveOpen: Only 8 or 16 bit samples are supported\r\n")));
ReturnValue = WAVERR_BADFORMAT;
goto ErrorReturn;
}
//
// Check if this routine is being called to just query for support of a
// particular format. If it is, we're done. The format is supported.
//
if (QueryFormatOnly == TRUE) {
DEBUGMSG(1, (TEXT("WaveOpen: QueryFormatOnly.\r\n")));
ReturnValue = MMSYSERR_NOERROR;
goto ErrorReturn;
}
//
// Attempt to allocate the stream. If we fail, it's currently in use, and
// an error is returned saying that the stream is allocated. The
// interlocked test exchange guarantees that only one thread opens the
// wave device, regardless if the MDD performs any locking.
//
DEBUGMSG(1, (TEXT("WaveOpen: Attempting to lock resource: %s\r\n"),
DIR_STR(WaveResource->WaveDirection)));
OldValue = InterlockedTestExchange(&WaveResource->InUse,
FALSE,
TRUE);
if (OldValue == TRUE) {
DEBUGMSG(1, (TEXT("WaveOpen: %s stream is in use\r\n"),
DIR_STR(WaveResource->WaveDirection)));
ReturnValue = MMSYSERR_ALLOCATED;
goto ErrorReturn;
}
else {
DEBUGMSG(1, (TEXT("WaveOpen: Locked %s stream for use\r\n"),
DIR_STR(WaveResource->WaveDirection)));
}
//
// Update the resource structure with the new format.
//
memcpy(&WaveResource->WaveFormat,
WaveFormat,
sizeof(*WaveFormat));
ReturnValue = MMSYSERR_NOERROR;
DEBUGMSG(1, (TEXT("\r\n")));
DEBUGMSG(1, (TEXT("*************************************** WaveOpen()\r\n")));
DEBUGMSG(1, (TEXT("** &WaveDevice 0x%8.8X\r\n"), &WaveDevice));
DEBUGMSG(1, (TEXT("** WaveDevice 0x%8.8X\r\n"), WaveDevice));
DEBUGMSG(1, (TEXT("** WaveDevice 0x%8.8X\r\n"), WaveDevice));
DEBUGMSG(1, (TEXT("** WaveDevice->ABPClkCtrlRegPrt 0x%8.8X\r\n"), WaveDevice->ABPClkCtrlRegPrt));
DEBUGMSG(1, (TEXT("** WaveDevice->AacRegPtr 0x%8.8X\r\n"), WaveDevice->AacRegPtr));
DEBUGMSG(1, (TEXT("** WaveDevice->AHBDmaCtrlRegPtr 0x%8.8X\r\n"), WaveDevice->AHBDmaCtrlRegPtr));
DEBUGMSG(1, (TEXT("** WaveDevice->DmaCtrlInput 0x%8.8X\r\n"), WaveDevice->DmaCtrlInput));
DEBUGMSG(1, (TEXT("** WaveDevice->DmaCtrlOutput 0x%8.8X\r\n"), WaveDevice->DmaCtrlOutput));
DEBUGMSG(1, (TEXT("** WaveDevice->DmaBufferSize 0x%8.8X\r\n"), WaveDevice->DmaBufferSize));
DEBUGMSG(1, (TEXT("** WaveDevice->DmaBuffersBase 0x%8.8X\r\n"), WaveDevice->DmaBuffersBase));
DEBUGMSG(1, (TEXT("** WaveDevice->DmaBuffersMdl 0x%8.8X\r\n"), WaveDevice->DmaBuffersMdl));
DEBUGMSG(1, (TEXT("** WaveDevice->DmaChannelInput 0x%8.8X\r\n"), WaveDevice->DmaChannelInput));
DEBUGMSG(1, (TEXT("** WaveDevice->DmaChannelOutput 0x%8.8X\r\n"), WaveDevice->DmaChannelOutput));
DEBUGMSG(1, (TEXT("** WaveDevice->AdapterObjectInput 0x%8.8X\r\n"), WaveDevice->AdapterObjectInput));
DEBUGMSG(1, (TEXT("** WaveDevice->AdapterObjectOutput 0x%8.8X\r\n"), WaveDevice->AdapterObjectOutput));
DEBUGMSG(1, (TEXT("** WaveDevice->MapRegsBaseInput 0x%8.8X\r\n"), WaveDevice->MapRegsBaseInput));
DEBUGMSG(1, (TEXT("** WaveDevice->MapRegsBaseOutput 0x%8.8X\r\n"), WaveDevice->MapRegsBaseOutput));
DEBUGMSG(1, (TEXT("** WaveDevice->SysIntrInput 0x%8.8X\r\n"), WaveDevice->SysIntrInput));
DEBUGMSG(1, (TEXT("** WaveDevice->SysIntrOutput 0x%8.8X\r\n"), WaveDevice->SysIntrOutput));
DEBUGMSG(1, (TEXT("** WaveDevice->CodecDevice 0x%8.8X\r\n"), WaveDevice->CodecDevice));
DEBUGMSG(1, (TEXT("** WaveDevice->SysIntrInputInitialized 0x%8.8X\r\n"), WaveDevice->SysIntrInputInitialized));
DEBUGMSG(1, (TEXT("** WaveDevice->SysIntrOutputInitialized 0x%8.8X\r\n"), WaveDevice->SysIntrOutputInitialized));
DEBUGMSG(1, (TEXT("** WaveDevice->Cs 0x%8.8X\r\n"), WaveDevice->Cs));
DEBUGMSG(1, (TEXT("\r\n")));
DEBUGMSG(1, (TEXT("** &WaveResource 0x%8.8X\r\n"), &WaveResource));
DEBUGMSG(1, (TEXT("** WaveResource 0x%8.8X\r\n"), WaveResource));
DEBUGMSG(1, (TEXT("** WaveResource->SysIntr 0x%8.8X\r\n"), WaveResource->SysIntr));
DEBUGMSG(1, (TEXT("** WaveResource->DmaBufferSize 0x%8.8X\r\n"), WaveResource->DmaBufferSize));
DEBUGMSG(1, (TEXT("** WaveResource->AdapterObject 0x%8.8X\r\n"), WaveResource->AdapterObject));
DEBUGMSG(1, (TEXT("** WaveResource->MapRegsBase 0x%8.8X\r\n"), WaveResource->MapRegsBase));
DEBUGMSG(1, (TEXT("** WaveResource->DmaBufferMdl 0x%8.8X\r\n"), WaveResource->DmaBufferMdl));
DEBUGMSG(1, (TEXT("** WaveResource->StartBuffer 0x%8.8X\r\n"), WaveResource->StartBuffer));
DEBUGMSG(1, (TEXT("** WaveResource->BufferAPhysAddr 0x%8.8X\r\n"), WaveResource->BufferAPhysAddr));
DEBUGMSG(1, (TEXT("** WaveResource->DmaBufferA 0x%8.8X\r\n"), WaveResource->DmaBufferA));
DEBUGMSG(1, (TEXT("** WaveResource->DmaBufferABytes 0x%8.8X\r\n"), WaveResource->DmaBufferABytes));
DEBUGMSG(1, (TEXT("** WaveResource->BufferBPhysAddr 0x%8.8X\r\n"), WaveResource->BufferBPhysAddr));
DEBUGMSG(1, (TEXT("** WaveResource->DmaBufferB 0x%8.8X\r\n"), WaveResource->DmaBufferB));
DEBUGMSG(1, (TEXT("** WaveResource->DmaBufferBBytes 0x%8.8X\r\n"), WaveResource->DmaBufferBBytes));
DEBUGMSG(1, (TEXT("** WaveResource->NextDMABuf 0x%8.8X\r\n"), WaveResource->NextDMABuf));
DEBUGMSG(1, (TEXT("** WaveResource->ABPClkCtrlRegPrt 0x%8.8X\r\n"), WaveResource->ABPClkCtrlRegPrt));
DEBUGMSG(1, (TEXT("** WaveResource->AacRegPtr 0x%8.8X\r\n"), WaveResource->AacRegPtr));
DEBUGMSG(1, (TEXT("** WaveResource->AHBDmaCtrlRegPtr 0x%8.8X\r\n"), WaveResource->AHBDmaCtrlRegPtr));
DEBUGMSG(1, (TEXT("** WaveResource->DmaRegPtr 0x%8.8X\r\n"), WaveResource->DmaRegPtr));
DEBUGMSG(1, (TEXT("** WaveResource->InUse 0x%8.8X\r\n"), WaveResource->InUse));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -