⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acm.c

📁 书中的主要程序文件。在打开例题的.dsw文件后,请读者在 tools菜单下的 Options 的 Directories 标签中选择 Executable files
💻 C
📖 第 1 页 / 共 5 页
字号:
//==========================================================================;
//
//  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 + -