📄 codec.c
字号:
// LPACMDRVFORMATSUGGEST padfs: Pointer to an ACMDRVFORMATSUGGEST
// structure that describes the source and destination (possibly with
// restrictions) for a conversion.
//
// 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 one or more of
// the destination restriction bits is not supported. It is strongly
// recommended that the driver support at least the following suggestion
// restriction bits:
//
// ACM_FORMATSUGGESTF_WFORMATTAG: The destination format tag must be
// the same as the wFormatTag member in the destination format header.
//
// ACM_FORMATSUGGESTF_NCHANNELS: The destination channel count must be
// the same as the nChannels member in the destination format header.
//
// ACM_FORMATSUGGESTF_NSAMPLESPERSEC: The destination samples per
// second must be the same as the nSamplesPerSec member in the
// destination format header.
//
// ACM_FORMATSUGGESTF_WBITSPERSAMPLE: The destination bits per sample
// must be the same as the wBitsPerSample member in the destination
// format header.
//
// If no destintation format can be suggested, then the driver should
// return ACMERR_NOTPOSSIBLE.
//
//--------------------------------------------------------------------------;
LRESULT FNLOCAL acmdFormatSuggest
(
PDRIVERINSTANCE pdi,
LPACMDRVFORMATSUGGEST padfs
)
{
#define ACMD_FORMAT_SUGGEST_SUPPORT (ACM_FORMATSUGGESTF_WFORMATTAG | \
ACM_FORMATSUGGESTF_NCHANNELS | \
ACM_FORMATSUGGESTF_NSAMPLESPERSEC |\
ACM_FORMATSUGGESTF_WBITSPERSAMPLE)
LPWAVEFORMATEX pwfxSrc;
LPWAVEFORMATEX pwfxDst;
DWORD fdwSuggest;
//
// grab the suggestion restriction bits and verify that we support
// the ones that are specified... an ACM driver must return the
// MMSYSERR_NOTSUPPORTED if the suggestion restriction bits specified
// are not supported.
//
fdwSuggest = (ACM_FORMATSUGGESTF_TYPEMASK & padfs->fdwSuggest);
if (~ACMD_FORMAT_SUGGEST_SUPPORT & fdwSuggest)
return (MMSYSERR_NOTSUPPORTED);
//
// get the source and destination formats in more convenient variables
//
pwfxSrc = padfs->pwfxSrc;
pwfxDst = padfs->pwfxDst;
//
//
//
//
switch (pwfxSrc->wFormatTag)
{
case WAVE_FORMAT_PCM:
//
// strictly verify that the source format is acceptable for
// this driver.
//
if (!pcmIsValidFormat(pwfxSrc))
break;
//
// if the destination format tag is restricted, verify that
// it is within our capabilities...
//
// this driver is able to encode only to GSM 6.10
//
if (ACM_FORMATSUGGESTF_WFORMATTAG & fdwSuggest)
{
if (WAVE_FORMAT_GSM610 != pwfxDst->wFormatTag)
return (ACMERR_NOTPOSSIBLE);
}
else
{
pwfxDst->wFormatTag = WAVE_FORMAT_GSM610;
}
//
// if the destination channel count is restricted, verify that
// it is within our capabilities...
//
// this driver is not able to change the number of channels
//
if (ACM_FORMATSUGGESTF_NCHANNELS & fdwSuggest)
{
if (pwfxSrc->nChannels != pwfxDst->nChannels)
return (ACMERR_NOTPOSSIBLE);
}
else
{
pwfxDst->nChannels = pwfxSrc->nChannels;
}
//
// if the destination samples per second is restricted, verify
// that it is within our capabilities...
//
// this driver is not able to change the sample rate
//
if (ACM_FORMATSUGGESTF_NSAMPLESPERSEC & fdwSuggest)
{
if (pwfxSrc->nSamplesPerSec != pwfxDst->nSamplesPerSec)
return (ACMERR_NOTPOSSIBLE);
}
else
{
pwfxDst->nSamplesPerSec = pwfxSrc->nSamplesPerSec;
}
//
// if the destination bits per sample is restricted, verify
// that it is within our capabilities...
//
if (ACM_FORMATSUGGESTF_WBITSPERSAMPLE & fdwSuggest)
{
if (GSM610_BITS_PER_SAMPLE != pwfxDst->wBitsPerSample)
return (ACMERR_NOTPOSSIBLE);
}
else
{
pwfxDst->wBitsPerSample = GSM610_BITS_PER_SAMPLE;
}
//
// at this point, we have filled in all fields except the
// following for our 'suggested' destination format:
//
// nAvgBytesPerSec
// nBlockAlign
// cbSize
// wSamplesPerBlock
//
pwfxDst->nBlockAlign = GSM610_BLOCKALIGNMENT(pwfxDst);
pwfxDst->nAvgBytesPerSec = GSM610_AVGBYTESPERSEC(pwfxDst);
pwfxDst->cbSize = GSM610_WFX_EXTRA_BYTES;
((LPGSM610WAVEFORMAT)pwfxDst)->wSamplesPerBlock
= GSM610_SAMPLESPERBLOCK(pwfxDst);
return (MMSYSERR_NOERROR);
case WAVE_FORMAT_GSM610:
//
// strictly verify that the source format is acceptable for
// this driver
//
if (!gsm610IsValidFormat(pwfxSrc))
return (ACMERR_NOTPOSSIBLE);
//
// if the destination format tag is restricted, verify that
// it is within our capabilities...
//
// this driver is able to decode to PCM
//
if (ACM_FORMATSUGGESTF_WFORMATTAG & fdwSuggest)
{
if (WAVE_FORMAT_PCM != pwfxDst->wFormatTag)
return (ACMERR_NOTPOSSIBLE);
}
else
{
pwfxDst->wFormatTag = WAVE_FORMAT_PCM;
}
//
// if the destination channel count is restricted, verify that
// it is within our capabilities...
//
// this driver is not able to change the number of channels
//
if (ACM_FORMATSUGGESTF_NCHANNELS & fdwSuggest)
{
if (pwfxSrc->nChannels != pwfxDst->nChannels)
return (ACMERR_NOTPOSSIBLE);
}
else
{
pwfxDst->nChannels = pwfxSrc->nChannels;
}
//
// if the destination samples per second is restricted, verify
// that it is within our capabilities...
//
// this driver is not able to change the sample rate
//
if (ACM_FORMATSUGGESTF_NSAMPLESPERSEC & fdwSuggest)
{
if (pwfxSrc->nSamplesPerSec != pwfxDst->nSamplesPerSec)
return (ACMERR_NOTPOSSIBLE);
}
else
{
pwfxDst->nSamplesPerSec = pwfxSrc->nSamplesPerSec;
}
//
// if the destination bits per sample is restricted, verify
// that it is within our capabilities...
//
// We prefer decoding to 16-bit PCM.
//
if (ACM_FORMATSUGGESTF_WBITSPERSAMPLE & fdwSuggest)
{
if ( (16 != pwfxDst->wBitsPerSample) && (8 != pwfxDst->wBitsPerSample) )
return (ACMERR_NOTPOSSIBLE);
}
else
{
pwfxDst->wBitsPerSample = 16;
}
//
// at this point, we have filled in all fields except the
// following for our 'suggested' destination format:
//
// nAvgBytesPerSec
// nBlockAlign
// cbSize !!! not used for PCM !!!
//
pwfxDst->nBlockAlign = PCM_BLOCKALIGNMENT((LPPCMWAVEFORMAT)pwfxDst);
pwfxDst->nAvgBytesPerSec = PCM_AVGBYTESPERSEC((LPPCMWAVEFORMAT)pwfxDst);
// pwfxDst->cbSize = not used;
return (MMSYSERR_NOERROR);
}
//
// can't suggest anything because either the source format is foreign
// or the destination format has restrictions that this ACM driver
// cannot deal with.
//
return (ACMERR_NOTPOSSIBLE);
} // acmdFormatSuggest()
//==========================================================================;
//
//
//
//
//==========================================================================;
//--------------------------------------------------------------------------;
//
// 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
)
{
UINT uFormatTag;
//
//
//
//
//
switch (ACM_FORMATTAGDETAILSF_QUERYMASK & fdwDetails)
{
case ACM_FORMATTAGDETAILSF_INDEX:
//
// if the index is too large, then they are asking for a
// non-existant format. return error.
//
if (ACM_DRIVER_MAX_FORMAT_TAGS <= padft->dwFormatTagIndex)
return (ACMERR_NOTPOSSIBLE);
uFormatTag = gauFormatTagIndexToTag[(UINT)padft->dwFormatTagIndex];
break;
case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
switch (padft->dwFormatTag)
{
case WAVE_FORMAT_UNKNOWN:
case WAVE_FORMAT_GSM610:
uFormatTag = WAVE_FORMAT_GSM610;
break;
case WAVE_FORMAT_PCM:
uFormatTag = WAVE_FORMAT_PCM;
break;
default:
return (ACMERR_NOTPOSSIBLE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -