📄 acm.c
字号:
pwfadpcm->wSamplesPerBlock = IMAAlgorithSamplesPerBlock(pwfxDst);
return (MMSYSERR_NOERROR);
case WAVE_FORMAT_IMA_ADPCM:
//
// strictly verify that the source format is acceptable for
// this driver
//
if (!IMAAlgorithIsValidFormat(pwfxSrc))
return (ACMERR_NOTPOSSIBLE);
//
// if the destination format tag is restricted, verify that
// it is within our capabilities...
//
// this driver is only 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...
//
// this driver is only able to decode to 16 or 8 bit
//
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(pwfxDst);
pwfxDst->nAvgBytesPerSec = pwfxDst->nSamplesPerSec *
pwfxDst->nBlockAlign;
// 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_IMA_ADPCM:
uFormatTag = WAVE_FORMAT_IMA_ADPCM;
break;
case WAVE_FORMAT_PCM:
uFormatTag = WAVE_FORMAT_PCM;
break;
default:
return (ACMERR_NOTPOSSIBLE);
}
break;
case ACM_FORMATTAGDETAILSF_FORMATTAG:
switch (padft->dwFormatTag)
{
case WAVE_FORMAT_IMA_ADPCM:
uFormatTag = WAVE_FORMAT_IMA_ADPCM;
break;
case WAVE_FORMAT_PCM:
uFormatTag = WAVE_FORMAT_PCM;
break;
default:
return (ACMERR_NOTPOSSIBLE);
}
break;
//
// if this ACM driver does not understand a query type, then
// return 'not supported'
//
default:
return (MMSYSERR_NOTSUPPORTED);
}
//
//
//
//
switch (uFormatTag)
{
case WAVE_FORMAT_PCM:
padft->dwFormatTagIndex = 0;
padft->dwFormatTag = WAVE_FORMAT_PCM;
padft->cbFormatSize = sizeof(PCMWAVEFORMAT);
padft->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_ACM;
padft->cStandardFormats = ACM_DRIVER_MAX_FORMATS_PCM;
//
// the ACM is responsible for the PCM format tag name
//
padft->szFormatTag[0] = '\0';
break;
case WAVE_FORMAT_IMA_ADPCM:
padft->dwFormatTagIndex = 1;
padft->dwFormatTag = WAVE_FORMAT_IMA_ADPCM;
padft->cbFormatSize = sizeof(WAVEFORMATEX) +
IMAALGORITH_WFX_EXTRA_BYTES;
padft->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_ACM;
padft->cStandardFormats = ACM_DRIVER_MAX_FORMATS_ADPCM;
LoadStringACM(pdi->hinst,
IDS_ACM_DRIVER_TAG_NAME,
padft->szFormatTag,
SIZEOFACMSTR(padft->szFormatTag));
break;
default:
return (ACMERR_NOTPOSSIBLE);
}
//
// return only the requested info
//
// the ACM will guarantee that the ACMFORMATTAGDETAILS structure
// passed is at least large enough to hold the base information of
// the details structure
//
padft->cbStruct = min(padft->cbStruct, sizeof(*padft));
//
//
//
return (MMSYSERR_NOERROR);
} // acmdFormatTagDetails()
//--------------------------------------------------------------------------;
//
// LRESULT acmdFormatDetails
//
// Description:
// This function handles the ACMDM_FORMAT_DETAILS message. This
// message is normally sent in response to an acmFormatDetails or
// acmFormatEnum function call. The purpose of this function is
// to get details about a specific format for a specified format tag
// supported by this ACM driver.
//
// Note that an ACM driver can return a zero length string for the
// format name if it wishes to have the ACM create a format string
// for it. This is strongly recommended to simplify internationalizing
// the driver--the ACM will automatically take care of that. The
// following formula is used to format a string by the ACM:
//
// <nSamplesPerSec> kHz, <bit depth> bit, [Mono | Stereo | nChannels]
//
// <bit depth> = <nAvgBytesPerSec> * 8 / nSamplesPerSec / nChannels;
//
// 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.
//
// LPACMFORMATDETAILS padf: Pointer to an ACMFORMATDETAILS structure
// that describes what format (for a specified format tag) to retrieve
// details for.
//
// DWORD fdwDetails: Flags defining what format for a specified 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_FORMATDETAILSF_INDEX: Indicates that a format index for the
// format tag was given in the dwFormatIndex member of the
// ACMFORMATDETAILS structure. The format details must be returned in
// the structure specified by padf. The index ranges from zero to one
// less than the cStandardFormats member returned in the
// ACMFORMATTAGDETAILS structure for a format tag.
//
// ACM_FORMATDETAILSF_FORMAT: Indicates that a WAVEFORMATEX structure
// pointed to by pwfx of the ACMFORMATDETAILS structure was given and
// the remaining details should be returned. The dwFormatTag member
// of the ACMFORMATDETAILS will be initialized to the same format
// tag as the pwfx member specifies. This query type may be used to
// get a string description of an arbitrary format structure.
//
// If the details for the specified format cannot be retrieved
// from this driver, then ACMERR_NOTPOSSIBLE should be returned.
//
//--------------------------------------------------------------------------;
LRESULT FNLOCAL acmdFormatDetails
(
PDRIVERINSTANCE pdi,
LPACMFORMATDETAILS padf,
DWORD fdwDetails
)
{
LPWAVEFORMATEX pwfx;
LPIMAALGORITHWAVEFORMAT pwfadpcm;
UINT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -