📄 wavemain.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
// Portions Copyright (c) Texas Instruments. All rights reserved.
//
//------------------------------------------------------------------------------
//
#include "wavemain.h"
//------------------------------------------------------------------------------
//
//
//
#ifdef DEBUG
DBGPARAM dpCurSettings =
{
TEXT("WaveDriver"), {
TEXT("EAC"),TEXT("Params"),TEXT("Verbose"),TEXT("Irq"),
TEXT("WODM"),TEXT("WIDM"),TEXT("PDD"),TEXT("MDD"),
TEXT("DMA"),TEXT("Misc"),TEXT("Midi"),TEXT("Modem"),
TEXT("Alloc"),TEXT("Function"),TEXT("Warning"),TEXT("Error") },
0xC000
};
#endif
//------------------------------------------------------------------------------
//
// defined in bt_ddi.h
//
// BT audio routing define
#if !defined(WODM_BT_SCO_AUDIO_CONTROL)
#define WODM_BT_SCO_AUDIO_CONTROL 500
#endif
//------------------------------------------------------------------------------
//
// Function: DllMain
//
//
BOOL CALLBACK DllMain(HANDLE hDLL,
DWORD dwReason,
LPVOID lpvReserved)
{
if ( dwReason==DLL_PROCESS_ATTACH )
{
DEBUGREGISTER((HMODULE)hDLL);
}
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_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>. 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_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)
{
return (DWORD)HardwareContext::CreateHWContext(Index);
}
// -----------------------------------------------------------------------------
//
// @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)
{
ASSERT(g_pHWContext!=NULL);
return g_pHWContext->Deinit();
}
// -----------------------------------------------------------------------------
//
// @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" PDWORD
WAV_Open( DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode)
{
// allocate and return handle context to efficiently verify caller trust level
return new DWORD(NULL); // assume untrusted. Can't tell for sure until WAV_IoControl
}
// -----------------------------------------------------------------------------
//
// @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(PDWORD pdwData)
{
// we trust the device manager to give us a valid context to free.
delete pdwData;
return(TRUE);
}
BOOL HandleWaveMessage(PMMDRV_MESSAGE_PARAMS pParams, DWORD *pdwResult)
{
// set the error code to be no error first
SetLastError(MMSYSERR_NOERROR);
UINT uMsg = pParams->uMsg;
UINT uDeviceId = pParams->uDeviceId;
DWORD dwParam1 = pParams->dwParam1;
DWORD dwParam2 = pParams->dwParam2;
DWORD dwUser = pParams->dwUser;
StreamContext *pStreamContext = (StreamContext *)dwUser;
DWORD dwRet=MMSYSERR_NOTSUPPORTED;
g_pHWContext->Lock();
// catch exceptions inside device lock, otherwise device will remain locked!
_try
{
switch (uMsg)
{
case WODM_GETNUMDEVS:
{
dwRet = g_pHWContext->GetNumOutputDevices();
break;
}
case WIDM_GETNUMDEVS:
{
dwRet = g_pHWContext->GetNumInputDevices();
break;
}
case WODM_GETDEVCAPS:
{
DeviceContext *pDeviceContext;
UINT NumDevs = g_pHWContext->GetNumOutputDevices();
if (pStreamContext)
{
pDeviceContext=pStreamContext->GetDeviceContext();
}
else
{
pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
}
dwRet = pDeviceContext->GetDevCaps((PVOID)dwParam1,dwParam2);
break;
}
case WIDM_GETDEVCAPS:
{
DeviceContext *pDeviceContext;
UINT NumDevs = g_pHWContext->GetNumInputDevices();
if (pStreamContext)
{
pDeviceContext=pStreamContext->GetDeviceContext();
}
else
{
pDeviceContext = g_pHWContext->GetInputDeviceContext(uDeviceId);
}
dwRet = pDeviceContext->GetDevCaps((PVOID)dwParam1,dwParam2);
break;
}
case WODM_OPEN:
{
DEBUGMSG(ZONE_WODM, (TEXT("WODM_OPEN\r\n")));
DeviceContext *pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
dwRet = pDeviceContext->OpenStream((LPWAVEOPENDESC)dwParam1, dwParam2, (StreamContext **)dwUser);
break;
}
case WODM_GETEXTDEVCAPS:
{
DeviceContext *pDeviceContext;
UINT NumDevs = g_pHWContext->GetNumOutputDevices();
if (pStreamContext)
{
pDeviceContext=pStreamContext->GetDeviceContext();
}
else
{
pDeviceContext = g_pHWContext->GetOutputDeviceContext(uDeviceId);
}
dwRet = pDeviceContext->GetExtDevCaps((PVOID)dwParam1,dwParam2);
break;
}
case WIDM_OPEN:
{
DEBUGMSG(ZONE_WIDM, (TEXT("WIDM_OPEN\r\n")));
DeviceContext *pDeviceContext = g_pHWContext->GetInputDeviceContext(uDeviceId);
dwRet = pDeviceContext->OpenStream((LPWAVEOPENDESC)dwParam1, dwParam2, (StreamContext **)dwUser);
break;
}
case WODM_CLOSE:
case WIDM_CLOSE:
{
DEBUGMSG(ZONE_WODM|ZONE_WIDM, (TEXT("WIDM_CLOSE/WODM_CLOSE\r\n")));
dwRet = pStreamContext->Close();
// Release stream context here, rather than inside StreamContext::Close, so that if someone
// (like CMidiStream) has subclassed Close there's no chance that the object will get released
// out from under them.
if (dwRet==MMSYSERR_NOERROR)
{
pStreamContext->Release();
}
break;
}
case WODM_RESTART:
case WIDM_START:
{
DEBUGMSG(ZONE_WODM|ZONE_WIDM, (TEXT("WODM_RESTART/WIDM_START\r\n")));
dwRet = pStreamContext->Run();
break;
}
case WODM_PAUSE:
case WIDM_STOP:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -