📄 codec.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) 1993-1999 Microsoft Corporation
//
//--------------------------------------------------------------------------;
//
// codec.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 "codec.h"
#include "gsm610.h"
#include "debug.h"
//
// array of supported format tags
//
//
const UINT gauFormatTagIndexToTag[] =
{
WAVE_FORMAT_PCM,
WAVE_FORMAT_GSM610
};
#define ACM_DRIVER_MAX_FORMAT_TAGS SIZEOF_ARRAY(gauFormatTagIndexToTag)
#define ACM_DRIVER_MAX_FILTER_TAGS 0
//
// array of sample rates supported
//
//
const UINT gauFormatIndexToSampleRate[] =
{
8000,
11025,
22050,
44100
};
//
// array of pcm bits per sample supported
//
//
const UINT gauPcmFormatIndexToBitsPerSample[] =
{
8,
16
};
const UINT ACM_DRIVER_MAX_SAMPLE_RATES = SIZEOF_ARRAY(gauFormatIndexToSampleRate);
#define ACM_DRIVER_MAX_CHANNELS GSM610_MAX_CHANNELS
//
// bits per sample supported
//
//
#define ACM_DRIVER_MAX_BITSPERSAMPLE_PCM 2
#define ACM_DRIVER_MAX_BITSPERSAMPLE_GSM610 1
//
// 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_FORMATS_PCM (ACM_DRIVER_MAX_SAMPLE_RATES * \
ACM_DRIVER_MAX_CHANNELS * \
ACM_DRIVER_MAX_BITSPERSAMPLE_PCM)
#define ACM_DRIVER_MAX_FORMATS_GSM610 (ACM_DRIVER_MAX_SAMPLE_RATES * \
ACM_DRIVER_MAX_CHANNELS * \
ACM_DRIVER_MAX_BITSPERSAMPLE_GSM610)
//--------------------------------------------------------------------------;
//
// This array describes the configuration settings for this codec.
//
// Each line in the realtime encode/decode rate listbox must have one of
// these structures to describe it. The type of line is defined in
// nFormatType, which can have one of the following values:
//
// CONFIG_RLF_NONUMBER - the string in idsFormat is displayed as is.
// CONFIG_RLF_MONOONLY - dwMonoRate is written into idsFormat, then
// displayed as a mono rate.
//
// The index to the gaRateListFormat array corresponds to the value which
// is stored as configuration information in the registry or .ini file.
// To find out if a certain conversion can be performed in real time,
// check that:
//
// SamplingRate <= gaRateListFormat[ConfigSetting].dwMonoRate / nChannels
//
// Note: The gaRateListFormat array must change when
// gauFormatIndexToSampleRate changes.
//
//--------------------------------------------------------------------------;
const RATELISTFORMAT gaRateListFormat[] =
{
{ CONFIG_RLF_NONUMBER, IDS_CONFIG_NORATES, 0 },
{ CONFIG_RLF_MONOONLY, IDS_CONFIG_MONOONLY, 8000 }, // gauFormatIndexToSampleRate[0]
{ CONFIG_RLF_MONOONLY, IDS_CONFIG_MONOONLY, 11025 }, // gauFormatIndexToSampleRate[1]
{ CONFIG_RLF_MONOONLY, IDS_CONFIG_MONOONLY, 22050 }, // gauFormatIndexToSampleRate[2]
{ CONFIG_RLF_MONOONLY, IDS_CONFIG_MONOONLY, 44100 }, // gauFormatIndexToSampleRate[3]
{ CONFIG_RLF_NONUMBER, IDS_CONFIG_ALLRATES, 88200 } // 2 * gauFormatIndexToSampleRate[3]
};
const UINT MSGSM610_CONFIG_NUMSETTINGS = SIZEOF_ARRAY( gaRateListFormat );
//==========================================================================;
//
//
//
//
//==========================================================================;
//--------------------------------------------------------------------------;
//
// int LoadStringCodec
//
// Description:
// This function should be used by all codecs 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
// codec.
//
// 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 LoadStringCodec LoadString
#else
#ifdef UNICODE
#define LoadStringCodec LoadStringW
#else
int FNGLOBAL LoadStringCodec
(
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 ( (16 != pwfx->wBitsPerSample) && (8 != pwfx->wBitsPerSample) )
return (FALSE);
//
// now verify that the block alignment is correct..
//
if (PCM_BLOCKALIGNMENT((LPPCMWAVEFORMAT)pwfx) != pwfx->nBlockAlign)
return (FALSE);
//
// finally, verify that avg bytes per second is correct
//
if (PCM_AVGBYTESPERSEC((LPPCMWAVEFORMAT)pwfx) != pwfx->nAvgBytesPerSec)
return (FALSE);
return (TRUE);
} // pcmIsValidFormat()
//--------------------------------------------------------------------------;
//
// BOOL gsm610IsValidFormat
//
// Description:
// This function verifies that a wave format header is a valid
// GSM 6.10 format 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 gsm610IsValidFormat
(
LPWAVEFORMATEX pwfx
)
{
if (NULL == pwfx)
return (FALSE);
if (WAVE_FORMAT_GSM610 != pwfx->wFormatTag)
return (FALSE);
//
// check channels
//
if ((pwfx->nChannels < 1) || (pwfx->nChannels > ACM_DRIVER_MAX_CHANNELS))
return (FALSE);
//
// now verify that the block alignment is correct..
//
if (GSM610_BLOCKALIGNMENT(pwfx) != pwfx->nBlockAlign)
return (FALSE);
//
// verify that avg bytes per second is correct
//
if (GSM610_AVGBYTESPERSEC(pwfx) != pwfx->nAvgBytesPerSec)
return (FALSE);
//
// check wBitsPerSample
//
if (GSM610_BITS_PER_SAMPLE != pwfx->wBitsPerSample)
return (FALSE);
//
// cbSize must be validated also..
//
if (GSM610_WFX_EXTRA_BYTES != pwfx->cbSize)
return (FALSE);
//
// check wSamplesPerBlock
//
if (GSM610_SAMPLESPERBLOCK(pwfx) != ((LPGSM610WAVEFORMAT)pwfx)->wSamplesPerBlock)
return (FALSE);
return (TRUE);
} // gsm610IsValidFormat()
//==========================================================================;
//
//
//
//
//==========================================================================;
//--------------------------------------------------------------------------;
//
// LRESULT acmdDriverOpen
//
// Description:
// This function is used to handle the DRV_OPEN message for the ACM
// driver. The driver is 'opened' for many reasons with the most common
// being in preperation for conversion work. It is very important that
// the driver be able to correctly handle multiple open driver
// instances.
//
// Read the comments for this function carefully!
//
// Note that multiple _streams_ can (and will) be opened on a single
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -