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

📄 acm.c

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

                default:
                    return (ACMERR_NOTPOSSIBLE);
            }
            break;


        case ACM_FORMATTAGDETAILSF_FORMATTAG:
            if (WAVE_FORMAT_PCM != padft->dwFormatTag)
                return (ACMERR_NOTPOSSIBLE);

            uFormatTag = WAVE_FORMAT_PCM;
            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_FILTER;
            padft->cStandardFormats = ACM_DRIVER_MAX_STANDARD_FORMATS_PCM;

            //
            //  the ACM is responsible for the PCM format tag name
            //
            padft->szFormatTag[0]   =  '\0';
            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;
    UINT                uFormatIndex;
    UINT                u;


    //
    //
    //
    //
    //
    switch (ACM_FORMATDETAILSF_QUERYMASK & fdwDetails)
    {
        //
        //  enumerate by index
        //
        //  verify that the format tag is something we know about and
        //  return the details on the 'standard format' supported by
        //  this driver at the specified index...
        //
        case ACM_FORMATDETAILSF_INDEX:
            //
            //  verify that the format tag is something we know about
            //
            if (WAVE_FORMAT_PCM != padf->dwFormatTag)
                return (ACMERR_NOTPOSSIBLE);

            if (ACM_DRIVER_MAX_STANDARD_FORMATS_PCM <= padf->dwFormatIndex)
                return (ACMERR_NOTPOSSIBLE);

            //
            //  put some stuff in more accessible variables--note that we
            //  bring variable sizes down to a reasonable size for 16 bit
            //  code...
            //
            pwfx = padf->pwfx;
            uFormatIndex = (UINT)padf->dwFormatIndex;

            //
            //  now fill in the format structure
            //
            pwfx->wFormatTag      = WAVE_FORMAT_PCM;

            u = uFormatIndex / (ACM_DRIVER_MAX_BITSPERSAMPLE_PCM * ACM_DRIVER_MAX_CHANNELS);
            pwfx->nSamplesPerSec  = gauFormatIndexToSampleRate[u]; 

            u = uFormatIndex % ACM_DRIVER_MAX_CHANNELS;
            pwfx->nChannels       = u + 1;

            u = (uFormatIndex / ACM_DRIVER_MAX_CHANNELS) % ACM_DRIVER_MAX_CHANNELS;
            pwfx->wBitsPerSample  = (WORD)gauFormatIndexToBitsPerSample[u]; 

            pwfx->nBlockAlign     = PCM_BLOCKALIGNMENT(pwfx);
            pwfx->nAvgBytesPerSec = PCM_AVGBYTESPERSEC(pwfx);


            //
            //  note that the cbSize field is NOT valid for PCM formats
            //
            //  pwfx->cbSize      = 0;
            break;


        //
        //  return details on specified format
        //
        //  the caller normally uses this to verify that the format is
        //  supported and to retrieve a string description...
        //
        case ACM_FORMATDETAILSF_FORMAT:
            if (!pcmIsValidFormat(padf->pwfx))
                return (ACMERR_NOTPOSSIBLE);

            break;


        default:
            //
            //  don't know how to do the query type passed--return 'not
            //  supported'.
            //
            return (MMSYSERR_NOTSUPPORTED);
    }


    //
    //  return the size of the valid information we are returning
    //
    //  the ACM will guarantee that the ACMFORMATDETAILS structure
    //  passed is at least large enough to hold the base structure 
    //
    //  note that we let the ACM create the format string for us since
    //  we require no special formatting (and don't want to deal with 
    //  internationalization issues, etc). simply set the string to
    //  a zero length.
    //
    padf->cbStruct    = min(padf->cbStruct, sizeof(*padf));
    padf->fdwSupport  = ACMDRIVERDETAILS_SUPPORTF_FILTER;
    padf->szFormat[0] = '\0';


    //
    //
    //
    return (MMSYSERR_NOERROR);
} // acmdFormatDetails()


//==========================================================================;
//
//
//
//
//==========================================================================;

//--------------------------------------------------------------------------;
//  
//  LRESULT acmdFilterTagDetails
//  
//  Description:
//  
//  
//  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.
//  
//      LPACMFILTERTAGDETAILS padft:
//  
//      DWORD fdwDetails:
//  
//  Return (LRESULT):
//  
//  
//--------------------------------------------------------------------------;

LRESULT FNLOCAL acmdFilterTagDetails
(
    PDRIVERINSTANCE         pdi,
    LPACMFILTERTAGDETAILS   padft,
    DWORD                   fdwDetails
)
{
    UINT                uIds;
    UINT                uFilterTag;

    //
    //
    //
    //
    //
    switch (ACM_FILTERTAGDETAILSF_QUERYMASK & fdwDetails)
    {
        case ACM_FILTERTAGDETAILSF_INDEX:
            //
            //  if the index is too large, then they are asking for a 
            //  non-existant filter.  return error.
            //
            if (ACM_DRIVER_MAX_FILTER_TAGS <= padft->dwFilterTagIndex)
                return (ACMERR_NOTPOSSIBLE);

            uFilterTag = (UINT)gadwFilterTagIndexToTag[(UINT)padft->dwFilterTagIndex];
            break;


        case ACM_FILTERTAGDETAILSF_LARGESTSIZE:
            switch (padft->dwFilterTag)
            {
                case WAVE_FILTER_UNKNOWN:
                case WAVE_FILTER_ECHO:
                    uFilterTag = WAVE_FILTER_ECHO;
                    break;

                case WAVE_FILTER_VOLUME:
                    uFilterTag = WAVE_FILTER_VOLUME;
                    break;

                default:
                    return (ACMERR_NOTPOSSIBLE);
            }
            break;


        case ACM_FILTERTAGDETAILSF_FILTERTAG:
            switch (padft->dwFilterTag)
            {
                case WAVE_FILTER_VOLUME:
                    uFilterTag = WAVE_FILTER_VOLUME;
                    break;

                case WAVE_FILTER_ECHO:
                    uFilterTag = WAVE_FILTER_ECHO;
                    break;

                default:
                    return (ACMERR_NOTPOSSIBLE);
            }
            break;


        //
        //  if this driver does not understand a query type, then
        //  return 'not supported'
        //
        default:
            return (MMSYSERR_NOTSUPPORTED);
    }



    //
    //
    //
    //
    switch (uFilterTag)
    {
        case WAVE_FILTER_VOLUME:
            padft->dwFilterTagIndex = 0;
            padft->dwFilterTag      = WAVE_FILTER_VOLUME;
            padft->cbFilterSize     = sizeof(VOLUMEWAVEFILTER);
            padft->fdwSupport       = ACMDRIVERDETAILS_SUPPORTF_FILTER;
            padft->cStandardFilters = ACM_DRIVER_MAX_VOLUME_FILTERS;

            uIds = IDS_ACM_DRIVER_TAG_NAME_VOLUME;
            break;

        case WAVE_FILTER_ECHO:
            padft->dwFilterTagIndex = 1;
            padft->dwFilterTag      = WAVE_FILTER_ECHO;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -