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

📄 codec.c

📁 gsm6.10标准的编解码例子
💻 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) 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 + -