📄 acm.c
字号:
// The return value is non-zero if the open instance can be closed.
// A zero return signifies that the ACM driver instance could not be
// closed.
//
// NOTE! It is _strongly_ recommended that the driver never fail to
// close. Note that the ACM will never allow a driver instance to
// be closed if there are open streams. An ACM driver does not need
// to check for this case.
//
//--------------------------------------------------------------------------;
LRESULT FNLOCAL acmdDriverClose
(
PDRIVERINSTANCE pdi
)
{
#ifdef IMAALGORITH_USECONFIGUR
//
// Release the registry key, if we allocated one.
//
if( NULL != pdi->hkey )
{
(void)RegCloseKey( pdi->hkey );
}
#endif
//
// check to see if we allocated instance data. if we did not, then
// immediately succeed.
//
if (NULL != pdi)
{
//
// close down the driver instance. this driver simply needs
// to free the instance data structure... note that if this
// 'free' fails, then this ACM driver probably trashed its
// heap; assume we didn't do that.
//
LocalFree((HLOCAL)pdi);
}
//
// non-zero return is success for DRV_CLOSE
//
return (1L);
} // acmdDriverClose()
//--------------------------------------------------------------------------;
//
// LRESULT acmdDriverConfigurure
//
// Description:
// This function is called to handle the DRV_[QUERY]CONFIGURURE messages.
// These messages are for 'Configururation' support of the driver.
// Normally this will be for 'hardware'--that is, a dialog should be
// displayed to Configurure ports, IRQ's, memory mappings, etc if it
// needs to. However, a software only ACM driver may also require
// Configururation for 'what is real time' or other quality vs time
// issues.
//
// The most common way that these messages are generated under Win 3.1
// and NT Product 1 is from the Control Panel's Drivers option. Other
// sources may generate these messages in future versions of Windows.
//
// Arguments:
// PDRIVERINSTANCE pdi: Pointer to private ACM driver instance structure.
// This structure is [optionally] allocated during the DRV_OPEN message
// which is handled by the acmdDriverOpen function.
//
// HWND hwnd: Handle to parent window to use when displaying the
// Configururation dialog box. An ACM driver is _required_ to display a
// modal dialog box using this hwnd argument as the parent. This
// argument may be (HWND)-1 which tells the driver that it is only
// being queried for Configururation support.
//
// LPDRVCONFIGURINFO pdci: Pointer to optional DRVCONFIGURINFO structure.
// If this argument is NULL, then the ACM driver should invent its own
// storage location.
//
// Return (LRESULT):
// If the driver is being 'queried' for Configururation support (that is,
// hwnd == (HWND)-1), then non-zero should be returned specifying
// the driver does support a Configururation dialog--or zero should be
// returned specifying that no Configururation dialog is supported.
//
// If the driver is being called to display the Configururation dialog
// (that is, hwnd != (HWND)-1), then one of the following values
// should be returned:
//
// DRVCNF_CANCEL (0x0000): specifies that the dialog was displayed
// and canceled by the user. this value should also be returned if
// no Configururation information was modified.
//
// DRVCNF_OK (0x0001): specifies that the dialog was displayed and
// the user pressed OK. This value should be returned even if the
// user didn't change anything - otherwise, the driver may not
// install properly.
//
// DRVCNF_RESTART (0x0002): specifies that the dialog was displayed
// and some Configururation information was changed that requires
// Windows to be restarted before the changes take affect. the driver
// should remain Configurured with current values until the driver
// has been 'rebooted'.
//
//--------------------------------------------------------------------------;
LRESULT FNLOCAL acmdDriverConfigurure
(
PDRIVERINSTANCE pdi,
HWND hwnd,
LPDRVCONFIGURINFO pdci
)
{
#ifdef IMAALGORITH_USECONFIGUR
INT_PTR n;
#endif
//
// first check to see if we are only being queried for Configururation
// support. if hwnd == (HWND)-1 then we are being queried and should
// return zero for 'not supported' and non-zero for 'supported'.
//
if ((HWND)-1 == hwnd)
{
#ifdef IMAALGORITH_USECONFIGUR
//
// this ACM driver supports a Configururation dialog box, so
// return non-zero...
//
return (1L);
#else
//
// this ACM driver does not support a Configururation dialog box, so
// return zero...
//
return (0L);
#endif
}
//
// we are being asked to bring up our Configururation dialog. if this
// driver supports a Configururation dialog box, then after the dialog
// is dismissed we must return one of the following values:
//
// DRVCNF_CANCEL (0x0000): specifies that the dialog was displayed
// and canceled by the user. this value should also be returned if
// no Configururation information was modified.
//
// DRVCNF_OK (0x0001): specifies that the dialog was displayed and
// the user pressed OK. This value should be returned even if the
// user didn't change anything - otherwise, the driver may not
// install properly.
//
// DRVCNF_RESTART (0x0002): specifies that the dialog was displayed
// and some Configururation information was changed that requires
// Windows to be restarted before the changes take affect. the driver
// should remain Configurured with current values until the driver
// has been 'rebooted'.
//
#ifdef IMAALGORITH_USECONFIGUR
if (NULL == pdci)
{
//
// !!!
//
DPF(2,"acmdDriverConfigurure returning CANCEL due to NULL==pdci.");
return (DRVCNF_CANCEL);
}
pdi->pdci = pdci;
//
// We may not have our Configur info yet if the driver has only been
// opened specifically for Configururation. So, read our Configururation
// using the alias passed in the DRVCONFIGURINFO structure passed
// through the DRV_CONFIGURURE message
//
#if (defined(WIN32) && !defined(UNICODE))
{
//
// We must translate the UNICODE alias name to an ANSI version
// that we can use.
//
LPSTR lpstr;
int iLen;
//
// Calculate required length without calling UNICODE APIs or CRT.
//
iLen = WideCharToMultiByte( GetACP(), 0, pdci->lpszDCIAliasName, -1,
NULL, 0, NULL, NULL );
lpstr = (LPSTR)GlobalAllocPtr( GPTR, iLen );
if (NULL != lpstr)
{
WideCharToMultiByte( GetACP(), 0, pdci->lpszDCIAliasName, iLen,
lpstr, iLen, NULL, NULL );
}
acmdDriverConfigurInit(pdi, lpstr); // Note: OK to pass lpstr==NULL
if (NULL != lpstr)
{
GlobalFreePtr( lpstr );
}
}
#else
acmdDriverConfigurInit(pdi, pdci->lpszDCIAliasName);
#endif // WIN32 && !UNICODE
n = DialogBoxParam(pdi->hinst,
IDD_CONFIGUR,
hwnd,
acmdDlgProcConfigurure,
(LPARAM)pdi);
pdi->pdci = NULL;
return ((LRESULT)n);
#else
//
// return DRVCNF_CANCEL--this ACM driver does not support Configururation
//
return (DRVCNF_CANCEL);
#endif // IMAALGORITH_USECONFIGUR
} // acmdDriverConfigurure()
//--------------------------------------------------------------------------;
//
// LRESULT acmdDriverDetails
//
// Description:
// This function handles the ACMDM_DRIVER_DETAILS message. The ACM
// driver is responsible for filling in the ACMDRIVERDETAILS structure
// with various information.
//
// NOTE! It is *VERY* important that you fill in your ACMDRIVERDETAILS
// structure correctly. The ACM and applications must be able to
// rely on this information.
//
// WARNING! The _reserved_ bits of any fields of the ACMDRIVERDETAILS
// structure are _exactly that_: RESERVED. Do NOT use any extra
// flag bits, etc. for custom information. The proper way to add
// custom capabilities to your ACM driver is this:
//
// o define a new message in the ACMDM_USER range.
//
// o an application that wishes to use one of these extra features
// should then:
//
// o open the driver with acmDriverOpen.
//
// o check for the proper wMid and wPid using acmDriverDetails.
//
// o send the 'user defined' message with acmDriverMessage
// to retrieve additional information, etc.
//
// o close the driver with acmDriverClose.
//
// Arguments:
// PDRIVERINSTANCE pdi: Pointer to private ACM driver instance structure.
// This structure is [optionally] allocated during the DRV_OPEN message
// which is handled by the acmdDriverOpen function.
//
// LPACMDRIVERDETAILS padd: Pointer to ACMDRIVERDETAILS structure to
// fill in for the caller. This structure may be larger or smaller than
// the current definition of ACMDRIVERDETAILS--cbStruct specifies the
// valid size.
//
// Return (LRESULT):
// The return value is zero (MMSYSERR_NOERROR) for success. Non-zero
// signifies that the driver details could not be retrieved.
//
// NOTE THAT THIS FUNCTION SHOULD NEVER FAIL! There are two possible
// error conditions:
//
// o if padd is NULL or an invalid pointer.
//
// o if cbStruct is less than four; in this case, there is not enough
// room to return the number of bytes filled in.
//
// Because these two error conditions are easily defined, the ACM
// will catch these errors. The driver does NOT need to check for these
// conditions.
//
//--------------------------------------------------------------------------;
LRESULT FNLOCAL acmdDriverDetails
(
PDRIVERINSTANCE pdi,
LPACMDRIVERDETAILS padd
)
{
ACMDRIVERDETAILS add;
DWORD cbStruct;
//
// it is easiest to fill in a temporary structure with valid info
// and then copy the requested number of bytes to the destination
// buffer.
//
cbStruct = min(padd->cbStruct, sizeof(ACMDRIVERDETAILS));
add.cbStruct = cbStruct;
//
// for the current implementation of an ACM driver, the fccType and
// fccComp members *MUST* always be ACMDRIVERDETAILS_FCCTYPE_AUDIOACM
// ('audc') and ACMDRIVERDETAILS_FCCCOMP_UNDEFINED (0) respectively.
//
add.fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOACM;
add.fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
//
// the manufacturer id (wMid) and product id (wPid) must be filled
// in with your company's _registered_ identifier's. for more
// information on these identifier's and how to get them registered
// contact G&G Lab and get the Multimedia Developer Registration Kit:
//
// G&G Lab Corporation
// Multimedia Technology Group
// One G&G Lab Way
// Redmond, WA 98052-6399
//
// Developer Services Phone: (800) 227-4679 x11771
//
// note that during the development phase or your ACM driver, you may
// use the reserved value of '0' for both wMid and wPid. however it
// is not acceptable to ship a driver with these values.
//
add.wMid = MM_G&G LAB;
add.wPid = MM_MSFT_ACM_IMAALGORITH;
//
// the vdwACM and vdwDriver members contain version information for
// the driver.
//
// vdwACM: must contain the version of the *ACM* that the driver was
// _designed_ for. this is the _minimum_ version number of the ACM
// that the driver will work with. this value must be >= V2.00.000.
//
// vdwDriver: the version of this ACM driver.
//
// ACM driver versions are 32 bit numbers broken into three parts as
// follows (note these parts are displayed as decimal values):
//
// bits 24 - 31: 8 bit _major_ version number
// bits 16 - 23: 8 bit _minor_ version number
// bits 0 - 15: 16 bit build number
//
add.vdwACM = VERSION_MSACM;
add.vdwDriver = VERSION_ACM_DRIVER;
//
// the following flags are used to specify the type of conversion(s)
// that the ACM driver supports. note that a driver may support one or
// more of these flags in any combination.
//
// ACMDRIVERDETAILS_SUPPORTF_ACM: this flag is set if the driver
// supports conversions from one format tag to another format tag. for
// example, if a converter compresses or decompresses WAVE_FORMAT_PCM
// and WAVE_FORMAT_IMA_ADPCM, then this bit should be set. this is
// true even if the data is not actually changed in size--for example
// a conversion from u-Law to A-Law will still set this bit because
// the format tags differ.
//
// ACMDRIVERDETAILS_SUPPORTF_CONVERTER: this flags is set if the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -