?? wavepdd.c
字號:
/*++
Copyright (c) 2004 BSQUARE Corporation. All rights reserved.
Module Name:
wavepdd.c
Module Description:
This module contains the pdd code of I2S audio driver
Author:
Ian Rae - January 2004 - Based heavily on PSC_AC97 code
Revision History:
--*/
#include <windows.h>
#include <bceddk.h>
#include "psc_i2s.h"
#include <wavedbg.h>
//#undef DEBUGMSG
//#define DEBUGMSG(x,y) RETAILMSG(1,y)
#define DMA_VERBOSE_DEBUG 0
#define DIR_STR(x) \
(((x) == WAPI_IN) ? TEXT("WAPI_IN") : TEXT("WAPI_OUT"))
extern HANDLE hAudioInterrupt;
//static
PWAVE_DEVICE_INSTANCE WaveDevice = NULL;
PWAVE_RESOURCE WaveInResource = NULL;
PWAVE_RESOURCE WaveOutResource = NULL;
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;
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) {
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: Au1550 PSC I2S"));
// All we support is 44.1 Stereo 16 bits. CE will nicely upconvert all audio for us.
OutputCapabilities->dwFormats = WAVE_FORMAT_4S16;
OutputCapabilities->wChannels = 2;
OutputCapabilities->dwSupport = WAVECAPS_VOLUME | WAVECAPS_LRVOLUME;
}
else {
InputCapabilities->wMid = MM_MICROSOFT;
InputCapabilities->wPid = MM_MSFT_GENERIC_WAVEIN;
InputCapabilities->vDriverVersion = MAKEWORD(0, 1); // v1.0
_stprintf(InputCapabilities->szPname,
TEXT("BSQUARE: Au1550 PSC I2S"));
//
// 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:
DEBUGMSG(ZONE_PDD, (TEXT("-Audio WaveGetDeviceCapabilities.\r\n")));
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;
DEBUGMSG(ZONE_PDD, (TEXT("+Audio WaveOpen.\r\n")));
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(ZONE_PDD, (
TEXT(" WaveOpen: 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(ZONE_PDD, (
TEXT(" WaveOpen: 1 or 2 channels is supported.\r\n")));
ReturnValue = WAVERR_BADFORMAT;
goto ErrorReturn;
}
//
// Sampling frequency. Only 11025, 22050, and 44100 Hz sample
// rates are supported.
//
if (WaveFormat->nSamplesPerSec != 11025 &&
WaveFormat->nSamplesPerSec != 22050 &&
WaveFormat->nSamplesPerSec != 44100) {
DEBUGMSG(ZONE_PDD, (
TEXT(" WaveOpen: 8.0 kHz, 11.025, 22.05, 44.1 and 48 kHz are")
TEXT(" 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(ZONE_PDD, (
TEXT(" WaveOpen: 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(ZONE_PDD, (
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.
//
OldValue = InterlockedTestExchange(&WaveResource->InUse,
FALSE,
TRUE);
if (OldValue == TRUE) {
ReturnValue = MMSYSERR_ALLOCATED;
goto ErrorReturn;
}
// Update the resource structure with the new format.
//
memcpy(&WaveResource->WaveFormat,
WaveFormat,
sizeof(*WaveFormat));
ReturnValue = MMSYSERR_NOERROR;
ErrorReturn:
DEBUGMSG(ZONE_PDD, (TEXT("-Audio WaveOpen.\r\n")));
return ReturnValue;
}
static
MMRESULT
WaveClose(
IN OUT PWAVE_RESOURCE WaveResource
)
/*++
Routine Description:
Closes a wave stream. This routine is dispatched by PDD_WaveProc. It is
expected that for every call to WaveOpen that succeeds, there will be one
and only one call to this routine.
Arguments:
WaveResource - Pointer to the wave resources structure corresponding to
the stream to be closed.
Return Value:
Returns an MMRESULT. MMSYSERR_NOERROR is returned on success.
--*/
{
MMRESULT ReturnValue;
ReturnValue = MMSYSERR_ERROR;
DEBUGMSG(ZONE_PDD, (TEXT("+Audio WaveClose.\r\n")));
//
// Verify that the resource was allocated and deallocate it by marking it
// as unused.
//
if (WaveResource->InUse == TRUE) {
WaveResource->MoreData = FALSE;
WaveResource->InUse = FALSE;
}
else {
DEBUGMSG(ZONE_PDD, (
TEXT(" WaveClose: Tried to close unallocated stream.\r\n")));
goto ErrorReturn;
}
ReturnValue = MMSYSERR_NOERROR;
ErrorReturn:
DEBUGMSG(ZONE_PDD, (TEXT("-Audio WaveClose.\r\n")));
return ReturnValue;
}
static
VOID
WaveStandby(
IN OUT PWAVE_RESOURCE WaveResource
)
/*++
Routine Description:
Powers down the devices associated with the specified direction. This is
dispatched by PDD_WaveProc. The MDD will call into PDD_WaveProc to have
this routine run when either of the AUDIO_STATE_OUT_STOPPED or
AUDIO_STATE_IN_STOPPED flags are returned.
Arguments:
WaveResource - Pointer to the wave resouces structure corresponding to the
wave stream that is to be placed in standby.
Return Value:
None.
--*/
{
DEBUGMSG(ZONE_PDD, (TEXT("+Audio WaveStandby.\r\n")));
ShutdownDma(WaveResource);
DEBUGMSG(ZONE_PDD, (TEXT("-Audio WaveStandby.\r\n")));
}
DWORD
PDD_AudioMessage(
UINT Message,
ULONG Param1,
ULONG Param2
)
{
DEBUGMSG(ZONE_PDD, (TEXT("Audio PDD_AudioMessage\r\n")));
return MMSYSERR_NOTSUPPORTED;
}
BOOL
PDD_AudioInitialize (
ULONG Index
)
{
WaveDevice = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT,
sizeof(*WaveDevice));
DEBUGMSG(ZONE_PDD,(L"+PDD_AudioInitialize\r\n"));
if (WaveDevice == NULL) {
DEBUGMSG(ZONE_PDD, (
TEXT("PDD_AudioInitialize: Failed to allocate configuration")
TEXT(" structure.\r\n")));
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto ErrorReturn;
}
//
// Read in the configuration values.
//
WaveDevice->DmaBufferSize = DMA_BUFFER_SIZE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -