📄 acm.c
字号:
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_FILTALGORITH;
//
// 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
// driver supports conversions on the same format tag. as an example,
// the PCM converter that is built into the ACM sets this bit (and only
// this bit) because it converts only between PCM formats (bits, sample
// rate).
//
// ACMDRIVERDETAILS_SUPPORTF_FILTER: this flag is set if the driver
// supports transformations on a single format tag but does change
// the base characteristics of the format (bit depth, sample rate, etc
// will remain the same). for example, a driver that changed the
// 'volume' of PCM data or applied a low pass filter would set this bit.
//
add.fdwSupport = ACMDRIVERDETAILS_SUPPORTF_FILTER;
//
// the number of individual format tags this ACM driver supports. for
// example, if a driver uses the WAVE_FORMAT_IMA_ADPCM and
// WAVE_FORMAT_PCM format tags, then this value would be two. if the
// driver only supports filtering on WAVE_FORMAT_PCM, then this value
// would be one. if this driver supported WAVE_FORMAT_ALAW,
// WAVE_FORMAT_MULAW and WAVE_FORMAT_PCM, then this value would be
// three. etc, etc.
//
add.cFormatTags = ACM_DRIVER_MAX_FORMAT_TAGS;
//
// the number of individual filter tags this ACM driver supports. if
// a driver supports no filters (ACMDRIVERDETAILS_SUPPORTF_FILTER is
// NOT set in the fdwSupport member), then this value must be zero.
//
add.cFilterTags = ACM_DRIVER_MAX_FILTER_TAGS;
//
// the remaining members in the ACMDRIVERDETAILS structure are sometimes
// not needed. because of this we make a quick check to see if we
// should go through the effort of filling in these members.
//
if (FIELD_OFFSET(ACMDRIVERDETAILS, hicon) < cbStruct)
{
//
// fill in the hicon member will a handle to a custom icon for
// the ACM driver. this allows the driver to be represented by
// an application graphically (usually this will be a company
// logo or something). if a driver does not wish to have a custom
// icon displayed, then simply set this member to NULL and a
// generic icon will be displayed instead.
//
add.hicon = LoadIcon(pdi->hinst, ICON_ACM_DRIVER);
//
// the short name and long name are used to represent the driver
// in a unique description. the short name is intended for small
// display areas (for example, in a menu or combo box). the long
// name is intended for more descriptive displays (for example,
// in an 'about box').
//
// NOTE! an ACM driver should never place formatting characters
// of any sort in these strings (for example CR/LF's, etc). it
// is up to the application to format the text.
//
LoadStringACM(pdi->hinst, IDS_ACM_DRIVER_SHORTNAME, add.szShortName, SIZEOFACMSTR(add.szShortName));
LoadStringACM(pdi->hinst, IDS_ACM_DRIVER_LONGNAME, add.szLongName, SIZEOFACMSTR(add.szLongName));
//
// the last three members are intended for 'about box' information.
// these members are optional and may be zero length strings if
// the driver wishes.
//
// NOTE! an ACM driver should never place formatting characters
// of any sort in these strings (for example CR/LF's, etc). it
// is up to the application to format the text.
//
if (FIELD_OFFSET(ACMDRIVERDETAILS, szCopyright) < cbStruct)
{
LoadStringACM(pdi->hinst, IDS_ACM_DRIVER_COPYRIGHT, add.szCopyright, SIZEOFACMSTR(add.szCopyright));
LoadStringACM(pdi->hinst, IDS_ACM_DRIVER_LICENSING, add.szLicensing, SIZEOFACMSTR(add.szLicensing));
LoadStringACM(pdi->hinst, IDS_ACM_DRIVER_FEATURES, add.szFeatures, SIZEOFACMSTR(add.szFeatures));
}
}
//
// now copy the correct number of bytes to the caller's buffer
//
_fmemcpy(padd, &add, (UINT)add.cbStruct);
//
// success!
//
return (MMSYSERR_NOERROR);
} // acmdDriverDetails()
//--------------------------------------------------------------------------;
//
// INT_PTR acmdDlgProcAbout
//
// Description:
//
// This dialog procedure is used for the ubiquitous about box.
//
// Note that we need to create a brush and store the handle between
// messages. In order to avoid using global memory, we store the
// handle to this brush in the Window structure using the DWLP_USER
// index.
//
// Arguments:
// HWND hwnd: Handle to window.
//
// UINT uMsg: Message being sent to the window.
//
// WPARAM wParam: Specific argument to message.
//
// LPARAM lParam: Specific argument to message.
//
// Return (INT_PTR):
// The return value is specific to the message that was received. For
// the most part, it is FALSE if this dialog procedure does not handle
// a message. Note, however, that we must return an HBRUSH for Windows
// to use for painting the background for the WM_CTLCOLORxxx messages.
//
//
//--------------------------------------------------------------------------;
#define ABOUT_BACKGROUNDCOLOR RGB(128,128,128)
#define ABOUT_HILIGHTCOLOR RGB(0,255,255)
INT_PTR FNEXPORT acmdDlgProcAbout
(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
HBRUSH hbr;
HWND hctrl;
UINT u;
hbr = (HBRUSH)GetWindowLongPtr( hwnd, DWLP_USER );
switch (uMsg)
{
case WM_INITDIALOG:
hbr = CreateSolidBrush( ABOUT_BACKGROUNDCOLOR );
SetWindowLongPtr( hwnd, DWLP_USER, (LONG_PTR)hbr );
return TRUE;
case WM_CTLCOLORSTATIC:
hctrl = GetDlgItem( hwnd, IDC_ABOUT_CATCHTHEWAVE );
if( (HWND)lParam == hctrl )
{
SetTextColor( (HDC)wParam, ABOUT_HILIGHTCOLOR );
}
// Fall through...
case WM_CTLCOLORDLG:
case WM_CTLCOLORBTN:
SetBkColor( (HDC)wParam, ABOUT_BACKGROUNDCOLOR );
return (INT_PTR)hbr;
case WM_COMMAND:
u = GET_WM_COMMAND_ID(wParam, lParam);
if ((IDOK == u) || (IDCANCEL == u))
{
EndDialog(hwnd, (IDOK == u));
}
return FALSE;
case WM_DESTROY:
DeleteObject( hbr );
return FALSE;
}
return (FALSE);
} // acmdDlgProcAbout()
//--------------------------------------------------------------------------;
//
// LRESULT acmdDriverAbout
//
// Description:
// This function is called to handle the ACMDM_DRIVER_ABOUT message.
// An ACM driver has the option of displaying its own 'about box' or
// letting the ACM (or calling application) display one for it. This
// message is normally sent by the Control Panel's Sound Mapper
// option.
//
// It is recommended that an ACM driver allow a default about box
// be displayed for it--there should be no reason to bloat the size
// of a driver to simply display copyright, etc information when that
// information is contained in the ACMDRIVERDETAILS structure.
//
// 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 about box support.
//
// Return (LRESULT):
// The return value is MMSYSERR_NOTSUPPORTED if the ACM driver does
// not support a custom dialog box. In this case, the ACM or calling
// application will display a generic about box using the information
// contained in the ACMDRIVERDETAILS structure returned by the
// ACMDM_DRIVER_DETAILS message.
//
// If the driver chooses to display its own dialog box, then after
// the dialog is dismissed by the user, MMSYSERR_NOERROR should be
// returned.
//
// If the hwnd argument is equal to (HWND)-1, then no dialog should
// be displayed (the driver is only being queried for support). The
// driver must still return MMSYSERR_NOERROR (supported) or
// MMSYSERR_NOTSUPPORTED (no custom about box supported).
//
//--------------------------------------------------------------------------;
LRESULT FNLOCAL acmdDriverAbout
(
PDRIVERINSTANCE pdi,
HWND hwnd
)
{
//
// first check to see if we are only being queried for custom about
// box support. if hwnd == (HWND)-1 then we are being queried and
// should return MMSYSERR_NOTSUPPORTED for 'not supported' and
// MMSYSERR_NOERROR for 'supported'.
//
if ((HWND)-1 == hwnd)
{
//
// this ACM driver supports a custom about box, so
// return MMSYSERR_NOERROR...
//
return (MMSYSERR_NOERROR);
}
//
// this driver does support a custom dialog, so display it. Note,
// however, that it is better to let the ACM display the About box
// for us - that means smaller code, and fewer bugs!
//
DialogBox( pdi->hinst, IDD_ABOUT, hwnd, acmdDlgProcAbout );
return (MMSYSERR_NOERROR);
} // acmdDriverAbout()
//==========================================================================;
//
//
//
//
//==========================================================================;
//--------------------------------------------------------------------------;
//
// LRESULT acmdFormatTagDetails
//
// Description:
// This function handles the ACMDM_FORMATTAG_DETAILS message. This
// message is normally sent in response to an acmFormatTagDetails or
// acmFormatTagEnum function call. The purpose of this function is
// to get details about a specific format tag supported by this ACM
// driver.
//
// 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.
//
// LPACMFORMATTAGDETAILS padft: Pointer to an ACMFORMATTAGDETAILS
// structure that describes what format tag to retrieve details for.
//
// DWORD fdwDetails: Flags defining what format tag to retrieve the
// details for.
//
// Return (LRESULT):
// The return value is zero (MMSYSERR_NOERROR) if this function
// succeeds with no errors. The return value is a non-zero error code
// if the function fails.
//
// The driver should return MMSYSERR_NOTSUPPORTED if the query type
// specified in fdwDetails is not supported. An ACM driver must
// support at least the following query types:
//
// ACM_FORMATTAGDETAILSF_INDEX: Indicates that a format tag index
// was given in the dwFormatTagIndex member of the ACMFORMATTAGDETAILS
// structure. The format tag and details must be returned in the
// structure specified by padft. The index ranges from zero to one less
// than the cFormatTags member returned in the ACMDRIVERDETAILS
// structure for this driver.
//
// ACM_FORMATTAGDETAILSF_FORMATTAG: Indicates that a format tag
// was given in the dwFormatTag member of the ACMFORMATTAGDETAILS
// structure. The format tag details must be returned in the structure
// specified by padft.
//
// ACM_FORMATTAGDETAILSF_LARGESTSIZE: Indicates that the details
// on the format tag with the largest format size in bytes must be
// returned. The dwFormatTag member will either be WAVE_FORMAT_UNKNOWN
// or the format tag to find the largest size for.
//
// If the details for the specified format tag cannot be retrieved
// from this driver, then ACMERR_NOTPOSSIBLE should be returned.
//
//--------------------------------------------------------------------------;
LRESULT FNLOCAL acmdFormatTagDetails
(
PDRIVERINSTANCE pdi,
LPACMFORMATTAGDETAILS padft,
DWORD fdwDetails
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -