📄 acm.c
字号:
//==========================================================================;
//
// 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.
//
// Copyright (c) 1992-1999 G&G Lab Corporation
//
//--------------------------------------------------------------------------;
//
// ACM.c
//
// Description:
// This file contains the DriverProc and other routines which respond
// to ACM messages.
//
//
//==========================================================================;
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <mmddk.h>
#include <mmreg.h>
#include <msacm.h>
#include <msacmdrv.h>
#include <memory.h>
#include "ACM.h"
#include "FiltAlgorith.h"
#include "debug.h"
//
// array of WAVE format tags supported.
//
// NOTE! if you change anything in this structure (order, addition, removal)
// you must also fix acmdFormatTagDetails!
//
const UINT gauFormatTagIndexToTag[] =
{
WAVE_FORMAT_PCM
};
#define ACM_DRIVER_MAX_FORMAT_TAGS SIZEOF_ARRAY(gauFormatTagIndexToTag)
//
// array of _standard_ sample rates supported
//
//
const UINT gauFormatIndexToSampleRate[] =
{
8000,
11025,
22050,
44100
};
#define ACM_DRIVER_MAX_SAMPLE_RATES SIZEOF_ARRAY(gauFormatIndexToSampleRate)
//
//
//
//
#define ACM_DRIVER_MAX_CHANNELS (FILTALGORITH_MAX_CHANNELS)
//
// array of bits per sample supported
//
//
const UINT gauFormatIndexToBitsPerSample[] =
{
8,
16
};
#define ACM_DRIVER_MAX_BITSPERSAMPLE_PCM SIZEOF_ARRAY(gauFormatIndexToBitsPerSample)
//
// number of formats we enumerate per channel is number of sample rates
// times number of channels times number of types (bits per sample).
//
#define ACM_DRIVER_MAX_STANDARD_FORMATS_PCM (ACM_DRIVER_MAX_SAMPLE_RATES * \
ACM_DRIVER_MAX_CHANNELS * \
ACM_DRIVER_MAX_BITSPERSAMPLE_PCM)
//
// Array of WAVE filter tags supported.
//
const DWORD gadwFilterTagIndexToTag[] =
{
WAVE_FILTER_VOLUME,
WAVE_FILTER_ECHO
};
#define ACM_DRIVER_MAX_FILTER_TAGS SIZEOF_ARRAY(gadwFilterTagIndexToTag)
//
// Array of filters supported.
//
const DWORD gdwFilterIndexToVolume[] =
{
0x00001000,
0x00002000,
0x00004000,
0x00006000,
0x00008000,
0x0000A000,
0x0000C000,
0x0000E000,
0x0000F000,
0x00011000,
0x00012000,
0x00014000,
0x00016000,
0x00018000,
0x0001A000,
0x0001C000,
0x00020000
};
#define ACM_DRIVER_MAX_VOLUME_FILTERS SIZEOF_ARRAY(gdwFilterIndexToVolume)
const DWORD gdwFilterIndexToDelay[] =
{
0x00000040,
0x00000080,
0x00000100,
0x00000180,
0x00000200,
0x00000300,
0x00000400,
0x00000800,
};
#define ACM_DRIVER_NUM_DELAY SIZEOF_ARRAY(gdwFilterIndexToDelay)
const DWORD gdwFilterIndexToEchoVol[] =
{
0x00001000,
0x00002000,
0x00004000,
0x00008000,
0x0000C000
};
#define ACM_DRIVER_NUM_ECHOVOL SIZEOF_ARRAY(gdwFilterIndexToEchoVol)
#define ACM_DRIVER_MAX_ECHO_FILTERS (ACM_DRIVER_NUM_DELAY * \
ACM_DRIVER_NUM_ECHOVOL)
//==========================================================================;
//
// SUPPORT ROUTINES FOR COMMON-BINARY ACMS.
//
//==========================================================================;
//--------------------------------------------------------------------------;
//
// int LoadStringACM
//
// Description:
// This function should be used by all ACMs to load resource strings
// which will be passed back to the ACM. It works correctly for all
// platforms, as follows:
//
// Win16: Compiled to LoadString to load ANSI strings.
//
// Win32: The 32-bit ACM always expects Unicode strings. Therefore,
// when UNICODE is defined, this function is compiled to
// LoadStringW to load a Unicode string. When UNICODE is
// not defined, this function loads an ANSI string, converts
// it to Unicode, and returns the Unicode string to the
// ACM.
//
// Note that you may use LoadString for other strings (strings which
// will not be passed back to the ACM), because these strings will
// always be consistent with the definition of UNICODE.
//
// Arguments:
// Same as LoadString, except that it expects an LPSTR for Win16 and a
// LPWSTR for Win32.
//
// Return (int):
// Same as LoadString.
//
//--------------------------------------------------------------------------;
#ifndef WIN32
#define LoadStringACM LoadString
#else
#ifdef UNICODE
#define LoadStringACM LoadStringW
#else
int FNGLOBAL LoadStringACM
(
HINSTANCE hinst,
UINT uID,
LPWSTR lpwstr,
int cch)
{
LPSTR lpstr;
int iReturn;
lpstr = (LPSTR)GlobalAlloc(GPTR, cch);
if (NULL == lpstr)
{
return 0;
}
iReturn = LoadStringA(hinst, uID, lpstr, cch);
if (0 == iReturn)
{
if (0 != cch)
{
lpwstr[0] = '\0';
}
}
else
{
MultiByteToWideChar( GetACP(), 0, lpstr, cch, lpwstr, cch );
}
GlobalFree((HGLOBAL)lpstr);
return iReturn;
}
#endif // UNICODE
#endif // WIN32
//==========================================================================;
//
//
//
//
//==========================================================================;
//--------------------------------------------------------------------------;
//
// BOOL pcmIsValidFormat
//
// Description:
// This function verifies that a wave format header is a valid PCM
// header that _this_ ACM driver can deal with.
//
// Arguments:
// LPWAVEFORMATEX pwfx: Pointer to format header to verify.
//
// Return (BOOL):
// The return value is non-zero if the format header looks valid. A
// zero return means the header is not valid.
//
//--------------------------------------------------------------------------;
BOOL FNLOCAL pcmIsValidFormat
(
LPWAVEFORMATEX pwfx
)
{
if (NULL == pwfx)
return (FALSE);
if (WAVE_FORMAT_PCM != pwfx->wFormatTag)
return (FALSE);
//
// verify nChannels member is within the allowed range
//
if ((pwfx->nChannels < 1) || (pwfx->nChannels > ACM_DRIVER_MAX_CHANNELS))
return (FALSE);
//
// only allow the bits per sample that we can encode and decode with
//
if ((8 != pwfx->wBitsPerSample) && (16 != pwfx->wBitsPerSample))
return (FALSE);
//
// now verify that the block alignment is correct..
//
if (PCM_BLOCKALIGNMENT(pwfx) != pwfx->nBlockAlign)
return (FALSE);
//
// verify samples per second is within our capabilities
//
if ((0L == pwfx->nSamplesPerSec) || (0x3FFFFFFF < pwfx->nSamplesPerSec))
{
return (FALSE);
}
//
// finally, verify that avg bytes per second is correct
//
if (PCM_AVGBYTESPERSEC(pwfx) != pwfx->nAvgBytesPerSec)
return (FALSE);
return (TRUE);
} // pcmIsValidFormat()
//--------------------------------------------------------------------------;
//
// BOOL volumeIsValidFilter
//
// Description:
// This function verifies that a wave filter header is a valid volume
// header that our volume converter can deal with.
//
// Arguments:
// LPWAVEFILTER pwf: Pointer to filter header to verify.
//
// Return (BOOL):
// The return value is non-zero if the format header looks valid. A
// zero return means the header is not valid.
//
// History:
// 06/05/93 Created.
//
//--------------------------------------------------------------------------;
BOOL FNLOCAL volumeIsValidFilter
(
LPWAVEFILTER pwf
)
{
if (!pwf)
return (FALSE);
if (pwf->cbStruct < sizeof(VOLUMEWAVEFILTER))
return (FALSE);
if (pwf->dwFilterTag != WAVE_FILTER_VOLUME)
return (FALSE);
if (0L != pwf->fdwFilter)
return (FALSE);
return (TRUE);
} // volumeIsValidFilter()
//--------------------------------------------------------------------------;
//
// BOOL echoIsValidFilter
//
// Description:
// This function verifies that a wave filter header is a valid echo
// header that our echo converter can deal with.
//
// Arguments:
// LPWAVEFILTER pwf: Pointer to filter header to verify.
//
// Return (BOOL):
// The return value is non-zero if the format header looks valid. A
// zero return means the header is not valid.
//
// History:
// 06/05/93 Created.
//
//--------------------------------------------------------------------------;
BOOL FNLOCAL echoIsValidFilter
(
LPWAVEFILTER pwf
)
{
LPECHOWAVEFILTER pwfEcho;
if (!pwf)
return (FALSE);
if (pwf->cbStruct < sizeof(ECHOWAVEFILTER))
return (FALSE);
if (pwf->dwFilterTag != WAVE_FILTER_ECHO)
return (FALSE);
if (0L != pwf->fdwFilter)
return (FALSE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -