📄 wav.cpp
字号:
//**********************************************************************
//
// Filename: wav.cpp
//
// Description: Includes the Wave interface to Device.exe.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to
// use this source code. For a copy of the EULA, please see the
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//
//**********************************************************************
#include "wavecommon.h"
#define IOCTL_DSHAL_MESSAGE CTL_CODE(FILE_DEVICE_SOUND, 5, METHOD_BUFFERED, FILE_ANY_ACCESS)
//
// Global Varaibles
//
WaveOut *gpWaveOut = (WaveOut *)0;
WaveIn *gpWaveIn = (WaveIn *)0;
I2SCodec *gpI2S = (I2SCodec *)0;
AC97Codec *gpAC97 = (AC97Codec *)0;
CodecInterface *gpCodec = (CodecInterface *)0;
//
// Debug Zones.
//
#ifdef DEBUG
DBGPARAM dpCurSettings =
{
TEXT("WaveDriver"),
{
TEXT("Test"),
TEXT("Params"),
TEXT("Verbose"),
TEXT("Interrupt"),
TEXT("WODM"),
TEXT("WIDM"),
TEXT("AC97"),
TEXT("DMA"),
TEXT("8"),
TEXT("Misc"),
TEXT("10"),
TEXT("IOcontrol"),
TEXT("Alloc"),
TEXT("Function"),
TEXT("Warning"),
TEXT("Error")
},
0xC000
// 0xC830
// 0xFFFF
};
#endif
class AudioDriver
{
public:
AudioDriver(void):
m_WaveOut(),
m_WaveIn(),
m_I2S(),
m_AC97(),
//m_I2SMixer(),
//m_AC97Mixer(),
m_bPowerDown(0)
{
};
~AudioDriver(void){};
MMRESULT Initialize(void);
DWORD WaveMessage(PMMDRV_MESSAGE_PARAMS pParms);
DWORD MixerMessage(PMMDRV_MESSAGE_PARAMS pParms);
//BOOL MixerEnabled(void) {return m_pMixer->MixerEnabled();};
BOOL bPowerDown;
AudioDriver* pNext;
void PowerDown( void );
void PowerUp( void );
private:
BOOL m_bPowerDown;
WaveOut m_WaveOut;
WaveIn m_WaveIn;
I2SCodec m_I2S;
AC97Codec m_AC97;
MixerDevice m_Mixer;
//
// Interfaces.
//
CodecInterface *m_pCodec;
};
DWORD ReadRegistryValue(HKEY hKey, PTSTR szValueName, DWORD dwDefault);
AudioDriver * g_pAudioDriverHead;
CRITICAL_SECTION g_AudioCritical;
//****************************************************************************
// dllentry
//****************************************************************************
//
//
//
extern "C" BOOL __stdcall dllentry
(
HANDLE hinstDLL,
DWORD Op,
LPVOID lpvReserved
)
{
HANDLE hCoreDll;
switch (Op) {
case DLL_PROCESS_ATTACH :
hCoreDll = LoadLibrary(TEXT("coredll.dll"));
if (hCoreDll == NULL) {
//
// ERROR! This is VERY bad if we can't LoadLibrary on COREDLL.DLL!!!
//
return(FALSE);
}
if (!GetProcAddress ((HINSTANCE)hCoreDll, TEXT("waveOutOpen"))) {
//
// The wave functions have not been exported by coredll, so
// we must not continue loading this driver.
//
FreeLibrary((HINSTANCE)hCoreDll);
return(FALSE);
}
FreeLibrary((HINSTANCE)hCoreDll);
InitializeCriticalSection( &g_AudioCritical );
DEBUGREGISTER((HINSTANCE)hinstDLL);
break;
case DLL_PROCESS_DETACH :
break;
case DLL_THREAD_DETACH :
break;
case DLL_THREAD_ATTACH :
break;
default :
break;
}
return TRUE;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @topic WAV Device Interface | Implements the WAVEDEV.DLL device
// interface. These functions are required for the device to
// be loaded by DEVICE.EXE.
//
// @xref <nl>
// <f WAV_Init>, <nl>
// <f WAV_Deinit>, <nl>
// <f WAV_Open>, <nl>
// <f WAV_Close>, <nl>
// <f WAV_Read>, <nl>
// <f WAV_Write>, <nl>
// <f WAV_Seek>, <nl>
// <f WAV_PowerUp>, <nl>
// <f WAV_PowerDown>, <nl>
// <f WAV_IOControl> <nl>
//
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @topic Designing a Waveform Audio Driver |
// A waveform audio driver is responsible for processing messages
// from the Wave API Manager (WAVEAPI.DLL) to playback and record
// waveform audio. Waveform audio drivers are implemented as
// dynamic link libraries that are loaded by DEVICE.EXE The
// default waveform audio driver is named WAVEDEV.DLL (see figure).
// The messages passed to the audio driver are similar to those
// passed to a user-mode Windows NT audio driver (such as mmdrv.dll).
//
// <bmp blk1_bmp>
//
// Like all device drivers loaded by DEVICE.EXE, the waveform
// audio driver must export the standard device functions,
// XXX_Init, XXX_Deinit, XXX_IoControl, etc (see
// <t WAV Device Interface>). The Waveform Audio Drivers
// have a device prefix of "WAV".
//
// Driver loading and unloading is handled by DEVICE.EXE and
// WAVEAPI.DLL. Calls are made to <f WAV_Init> and <f WAV_Deinit>.
// When the driver is opened by WAVEAPI.DLL calls are made to
// <f WAV_Open> and <f WAV_Close>. On system power up and power down
// calls are made to <f WAV_PowerUp> and <f WAV_PowerDown>. All
// other communication between WAVEAPI.DLL and WAVEDEV.DLL is
// done by calls to <f WAV_IOControl>. The other WAV_xxx functions
// are not used.
//
// @xref <nl>
// <t Designing a Waveform Audio PDD> <nl>
// <t WAV Device Interface> <nl>
// <t Wave Input Driver Messages> <nl>
// <t Wave Output Driver Messages> <nl>
//
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | WAV_Deinit | Device deinitialization routine
//
// @parm DWORD | dwData | value returned from WAV_Init call
//
// @rdesc Returns TRUE for success, FALSE for failure.
//
// -----------------------------------------------------------------------------
extern "C" BOOL WAV_Deinit
(
DWORD dwData
)
{
AudioDriver * pAudioDrv = (AudioDriver *)dwData;
EnterCriticalSection( &g_AudioCritical);
if( pAudioDrv== g_pAudioDriverHead )
{
g_pAudioDriverHead=pAudioDrv->pNext;
}
else
{
AudioDriver * pAudioList=g_pAudioDriverHead;
while( pAudioList->pNext)
{
if( pAudioList->pNext == pAudioDrv )
{
pAudioList->pNext= pAudioList->pNext->pNext;
break;
}
pAudioList=pAudioList->pNext;
}
}
LeaveCriticalSection(&g_AudioCritical);
if(pAudioDrv)
{
delete pAudioDrv;
}
return TRUE;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | WAV_Init | Device initialization routine
//
// @parm DWORD | dwInfo | info passed to RegisterDevice
//
// @rdesc Returns a DWORD which will be passed to Open & Deinit or NULL if
// unable to initialize the device.
//
// -----------------------------------------------------------------------------
extern "C" DWORD WAV_Init
(
DWORD Index
)
{
AudioDriver * pAudioDrv = new AudioDriver();
DWORD dwRet;
if(pAudioDrv)
{
dwRet = pAudioDrv->Initialize();
if(!MMSUCCESS(dwRet))
{
delete pAudioDrv;
pAudioDrv = 0;
}
}
EnterCriticalSection(&g_AudioCritical);
pAudioDrv->pNext =g_pAudioDriverHead;
g_pAudioDriverHead=pAudioDrv;
LeaveCriticalSection(&g_AudioCritical);
return ((DWORD)pAudioDrv);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | WAV_Open | Device open routine
//
// @parm DWORD | dwData | Value returned from WAV_Init call (ignored)
//
// @parm DWORD | dwAccess | Requested access (combination of GENERIC_READ
// and GENERIC_WRITE) (ignored)
//
// @parm DWORD | dwShareMode | Requested share mode (combination of
// FILE_SHARE_READ and FILE_SHARE_WRITE) (ignored)
//
// @rdesc Returns a DWORD which will be passed to Read, Write, etc or NULL if
// unable to open device.
//
// -----------------------------------------------------------------------------
extern "C" DWORD WAV_Open
(
DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("WAV_Open(0x%X)\r\n"), dwData));
AudioDriver **ppAudioDriver;
//
// Allocate a pointer to the audio driver instance.
//
ppAudioDriver = new (AudioDriver *);
*ppAudioDriver = (AudioDriver *)dwData;
return (DWORD)ppAudioDriver;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | WAV_Close | Device close routine
//
// @parm DWORD | dwOpenData | Value returned from WAV_Open call
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// -----------------------------------------------------------------------------
extern "C" BOOL WAV_Close(
DWORD dwData
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("WAV_Close(0x%X)\r\n"), dwData));
delete (AudioDriver **)dwData;
return TRUE;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | WAV_Read | Device read routine
//
// @parm DWORD | dwOpenData | Value returned from WAV_Open call (ignored)
//
// @parm LPVOID | pBuf | Buffer to receive data (ignored)
//
// @parm DWORD | len | Maximum length to read (ignored)
//
// @rdesc Returns 0 always. WAV_Read should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f WAV_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD WAV_Read
(
DWORD dwData,
LPVOID pBuf,
DWORD Len
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("WAV_Read(0x%X, 0x%X, %d)\r\n"),
dwData, pBuf, Len));
// Return length read
return 0;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | WAV_Write | Device write routine
//
// @parm DWORD | dwOpenData | Value returned from WAV_Open call (ignored)
//
// @parm LPCVOID | pBuf | Buffer containing data (ignored)
//
// @parm DWORD | len | Maximum length to write (ignored)
//
// @rdesc Returns 0 always. WAV_Write should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f WAV_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD WAV_Write
(
DWORD dwData,
LPCVOID pBuf,
DWORD Len
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("WAV_Write(0x%X, 0x%X, %d)\r\n"),
dwData, pBuf, Len));
// return number of bytes written (or -1 for error)
return 0;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | WAV_Seek | Device seek routine
//
// @parm DWORD | dwOpenData | Value returned from WAV_Open call (ignored)
//
// @parm long | pos | Position to seek to (relative to type) (ignored)
//
// @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END (ignored)
//
// @rdesc Returns -1 always. WAV_Seek should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f WAV_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD WAV_Seek
(
DWORD dwData,
long pos,
DWORD type
)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT("WAV_Seek(0x%X, %d, %d)\r\n"), dwData,
pos, type));
// return an error
return (DWORD)-1;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | WAV_PowerUp | Device powerup routine
//
// @comm Called to restore device from suspend mode. Cannot call any
// routines aside from those in the dll in this call.
//
// -----------------------------------------------------------------------------
extern "C" VOID WAV_PowerUp(VOID)
{
AudioDriver * pAudio=g_pAudioDriverHead;
for(; pAudio; )
{
pAudio->PowerUp( );
pAudio=pAudio->pNext;
}
//WMDD_PowerHandler(FALSE);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | WAV_PowerDown | Device powerdown routine
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -