Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

579 lines
16 KiB

/////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
//
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
//
// Other brand and product names used herein are trademarks of their respective owners.
//
// The entire program and user interface including the structure, sequence, selection,
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
// by "1" and "2," and each dialog message are protected by copyrights registered in
// the United States and by international treaties.
//
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
//
// Active Voice Corporation
// Seattle, Washington
// USA
//
/////////////////////////////////////////////////////////////////////////////////////////
////
// wavfmt.c - wave format functions
////
#include "winlocal.h"
#include <stdlib.h>
#include <stddef.h>
#include "wavfmt.h"
#include "calc.h"
#include "mem.h"
#include "trace.h"
////
// private definitions
////
#define SAMPLERATE_DEFAULT 11025
#define SAMPLERATE_MAX 64000
#define SAMPLERATE_MIN 1000
#define SAMPLESIZE_DEFAULT 8
#define SAMPLESIZE_MAX 32
#define SAMPLESIZE_MIN 0
#define CHANNELS_DEFAULT 1
#define CHANNELS_MAX 2
#define CHANNELS_MIN 1
////
// public functions
////
// WavFormatPcm - fill WAVEFORMATEX struct based on PCM characteristics
// <nSamplesPerSec> (i) sample rate
// -1 default sample rate (11025)
// <nBitsPerSample> (i) sample size
// -1 default sample size (8)
// <nChannels> (i) number of channels (1=mono, 2=stereo)
// -1 default (mono)
// <lpwfx> (o) pointer to output buffer
// NULL allocate new buffer to hold result
// return pointer to WAVEFORMATEX struct, NULL if error
//
// NOTE: if <lpwfx> points to a WAVEFORMATEX struct, this struct
// is filled in, and this function returns <lpwfx>.
// If <lpwfx> is NULL, space is dynamically allocated for the output
// buffer, and this function returns a pointer to the output buffer.
// Use WavFormatFree() to free the buffer.
//
LPWAVEFORMATEX DLLEXPORT WINAPI WavFormatPcm(long nSamplesPerSec,
WORD nBitsPerSample, WORD nChannels, LPWAVEFORMATEX lpwfx)
{
BOOL fSuccess = TRUE;
LPWAVEFORMATEX lpwfxNew = lpwfx;
if (nSamplesPerSec == -1)
nSamplesPerSec = SAMPLERATE_DEFAULT;
if (nBitsPerSample == -1)
nBitsPerSample = SAMPLESIZE_DEFAULT;
if (nChannels == -1)
nChannels = CHANNELS_DEFAULT;
// user passed struct to fill
//
if (lpwfx != NULL && IsBadReadPtr(lpwfx, sizeof(WAVEFORMATEX)))
fSuccess = TraceFALSE(NULL);
// we allocate struct to fill
//
else if (lpwfx == NULL
&& (lpwfxNew = WavFormatAlloc(sizeof(WAVEFORMATEX))) == NULL)
fSuccess = TraceFALSE(NULL);
// fill the struct
//
else
{
lpwfxNew->wFormatTag = WAVE_FORMAT_PCM;
lpwfxNew->nChannels = nChannels;
lpwfxNew->nSamplesPerSec = nSamplesPerSec;
lpwfxNew->nBlockAlign = nChannels * (((nBitsPerSample - 1) / 8) + 1);
lpwfxNew->nAvgBytesPerSec = lpwfxNew->nBlockAlign * nSamplesPerSec;
lpwfxNew->wBitsPerSample = nBitsPerSample;
lpwfxNew->cbSize = 0;
}
return fSuccess ? lpwfxNew : NULL;
}
// WavFormatAlloc - allocate WAVEFORMATEX struct buffer
// <cbSize> (i) size of struct, including extra bytes
// return pointer to WAVEFORMATEX struct, NULL if error
//
// NOTE: use WavFormatFree() to free the buffer.
//
LPWAVEFORMATEX DLLEXPORT WINAPI WavFormatAlloc(WORD cbSize)
{
BOOL fSuccess = TRUE;
LPWAVEFORMATEX lpwfx;
if (cbSize < sizeof(WAVEFORMATEX))
fSuccess = TraceFALSE(NULL);
// memory is allocated such that the client owns it
//
else if ((lpwfx = (LPWAVEFORMATEX) MemAlloc(NULL, cbSize, 0)) == NULL)
fSuccess = TraceFALSE(NULL);
else
lpwfx->cbSize = cbSize - sizeof(WAVEFORMATEX);
return fSuccess ? lpwfx : NULL;
}
// WavFormatDup - duplicate WAVEFORMATEX structure
// <lpwfx> (i) pointer to WAVEFORMATEX struct
// return pointer to new WAVEFORMATEX struct, NULL if error
//
// NOTE: use WavFormatFree() to free the buffer.
//
LPWAVEFORMATEX DLLEXPORT WINAPI WavFormatDup(LPWAVEFORMATEX lpwfx)
{
BOOL fSuccess = TRUE;
LPWAVEFORMATEX lpwfxNew;
if (lpwfx == NULL)
fSuccess = TraceFALSE(NULL);
else if (IsBadReadPtr(lpwfx, WavFormatGetSize(lpwfx)))
fSuccess = TraceFALSE(NULL);
else if ((lpwfxNew = WavFormatAlloc((WORD)
WavFormatGetSize(lpwfx))) == NULL)
fSuccess = TraceFALSE(NULL);
else
MemCpy(lpwfxNew, lpwfx, WavFormatGetSize(lpwfx));
return fSuccess ? lpwfxNew : NULL;
}
// WavFormatFree - free WAVEFORMATEX struct
// <lpwfx> (i) pointer returned from WavFormatAlloc/Dup/Pcm
// return 0 if success
//
int DLLEXPORT WINAPI WavFormatFree(LPWAVEFORMATEX lpwfx)
{
BOOL fSuccess = TRUE;
if (lpwfx == NULL)
fSuccess = TraceFALSE(NULL);
else if ((lpwfx = MemFree(NULL, lpwfx)) != NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? 0 : -1;
}
// WavFormatIsValid - check format for validity
// <lpwfx> (i) pointer to WAVEFORMATEX struct
// return TRUE if valid format
//
BOOL DLLEXPORT WINAPI WavFormatIsValid(LPWAVEFORMATEX lpwfx)
{
BOOL fSuccess = TRUE;
if (lpwfx == NULL)
fSuccess = TraceFALSE(NULL);
else if (IsBadReadPtr(lpwfx, sizeof(WAVEFORMATEX)))
fSuccess = TraceFALSE(NULL);
else if (IsBadReadPtr(lpwfx, WavFormatGetSize(lpwfx)))
fSuccess = TraceFALSE(NULL);
else if (lpwfx->nSamplesPerSec < SAMPLERATE_MIN ||
lpwfx->nSamplesPerSec > SAMPLERATE_MAX)
fSuccess = TraceFALSE(NULL);
else if (lpwfx->wBitsPerSample < SAMPLESIZE_MIN ||
lpwfx->wBitsPerSample > SAMPLESIZE_MAX)
fSuccess = TraceFALSE(NULL);
else if (lpwfx->nChannels < CHANNELS_MIN ||
lpwfx->nChannels > CHANNELS_MAX)
fSuccess = TraceFALSE(NULL);
return fSuccess ? TRUE : FALSE;
}
// WavFormatCmp - compare one format with another
// <lpwfx1> (i) pointer to WAVEFORMATEX struct
// <lpwfx2> (i) pointer to WAVEFORMATEX struct
// return 0 if identical
//
#if 0
// NOTE: this function does NOT compare the cbSize field or the extra bytes
#else
// NOTE: this function does NOT compare the extra bytes beyond the cbSize field
#endif
//
int DLLEXPORT WINAPI WavFormatCmp(LPWAVEFORMATEX lpwfx1, LPWAVEFORMATEX lpwfx2)
{
BOOL fSuccess = TRUE;
int nCmp = 0; // assume identical
if (!WavFormatIsValid(lpwfx1))
fSuccess = TraceFALSE(NULL);
else if (!WavFormatIsValid(lpwfx2))
fSuccess = TraceFALSE(NULL);
else
{
#if 0
// compare up to (but not including) the cbSize field
//
nCmp = MemCmp(lpwfx1, lpwfx2,
offsetof(WAVEFORMATEX, cbSize));
#else
// compare up to and including the cbSize field
//
nCmp = MemCmp(lpwfx1, lpwfx2, sizeof(WAVEFORMATEX));
#endif
}
return fSuccess ? nCmp : -1;
}
// WavFormatCopy - copy one format to another
// <lpwfxDst> (i) pointer to destination WAVEFORMATEX struct
// <lpwfxSrc> (i) pointer to source WAVEFORMATEX struct
// return 0 if success
//
#if 0
// NOTE: this function does NOT copy the cbSize field or the extra bytes
#else
// NOTE: make sure lpwfxDst points to enough memory to contain the entire
// WAVEFORMATEX struct plus any extra bytes beyond it
#endif
//
int DLLEXPORT WINAPI WavFormatCopy(LPWAVEFORMATEX lpwfxDst, LPWAVEFORMATEX lpwfxSrc)
{
BOOL fSuccess = TRUE;
if (!WavFormatIsValid(lpwfxSrc))
fSuccess = TraceFALSE(NULL);
else if (lpwfxDst == NULL)
fSuccess = TraceFALSE(NULL);
#if 0
// make sure destination is at least as big as WAVEFORMATEX struct
//
else if (IsBadReadPtr(lpwfxDst, sizeof(WAVEFORMATEX))
fSuccess = TraceFALSE(NULL);
else
{
// copy up to (but not including) the cbSize field
//
MemCpy(lpwfxDst, lpwfxSrc,
offsetof(WAVEFORMATEX, cbSize));
}
#else
// make sure destination is at least as big as source
//
else if (IsBadReadPtr(lpwfxDst, WavFormatGetSize(lpwfxSrc)))
fSuccess = TraceFALSE(NULL);
else
{
// copy entire structure, including any extra bytes
//
MemCpy(lpwfxDst, lpwfxSrc, WavFormatGetSize(lpwfxSrc));
}
#endif
return fSuccess ? 0 : -1;
}
// WavFormatGetSize - check size of format structure
// <lpwfx> (i) pointer to WAVEFORMATEX struct
// return size of structure, 0 if error
//
int DLLEXPORT WINAPI WavFormatGetSize(LPWAVEFORMATEX lpwfx)
{
BOOL fSuccess = TRUE;
int sizwfx = 0;
if (lpwfx == NULL)
fSuccess = TraceFALSE(NULL);
// ignore cbSize value if pcm format
//
else if (lpwfx->wFormatTag == WAVE_FORMAT_PCM)
sizwfx = sizeof(WAVEFORMATEX);
else
sizwfx = sizeof(WAVEFORMATEX) + lpwfx->cbSize;
return fSuccess ? sizwfx : 0;
}
// WavFormatDump - dump WAVEFORMATEX struct to debug
// <lpwfx> (i) pointer to WAVEFORMATEX struct
// return 0 if success
//
int DLLEXPORT WINAPI WavFormatDump(LPWAVEFORMATEX lpwfx)
{
BOOL fSuccess = TRUE;
if (lpwfx == NULL)
fSuccess = TraceFALSE(NULL);
else if (IsBadReadPtr(lpwfx, sizeof(WAVEFORMATEX)))
fSuccess = TraceFALSE(NULL);
else
{
TracePrintf_7(NULL, 1,
TEXT("struct tWAVEFORMATEX\n")
TEXT("{\n")
TEXT("\tWORD\twFormatTag = %u;\n")
TEXT("\tWORD\tnChannels = %u;\n")
TEXT("\tDWORD\tnSamplesPerSec = %lu;\n")
TEXT("\tDWORD\tnAvgBytesPerSec = %lu;\n")
TEXT("\tWORD\tnBlockAlign = %u;\n")
TEXT("\tWORD\twBitsPerSample = %u;\n")
TEXT("\tWORD\tcbSize = %u;\n")
TEXT("} WAVEFORMATEX\n"),
(unsigned int) lpwfx->wFormatTag,
(unsigned int) lpwfx->nChannels,
(unsigned long) lpwfx->nSamplesPerSec,
(unsigned long) lpwfx->nAvgBytesPerSec,
(unsigned int) lpwfx->nBlockAlign,
(unsigned int) lpwfx->wBitsPerSample,
(unsigned int) lpwfx->cbSize);
}
return fSuccess ? 0 : -1;
}
// WavFormatBytesToMilleseconds - convert bytes to milleseconds
// <lpwfx> (i) pointer to WAVEFORMATEX struct
// <dwBytes> (i) bytes
// return milleseconds
//
DWORD DLLEXPORT WINAPI WavFormatBytesToMilleseconds(LPWAVEFORMATEX lpwfx, DWORD dwBytes)
{
if (lpwfx == NULL || lpwfx->nAvgBytesPerSec == 0)
return 0;
else
return MULDIVU32(dwBytes, 1000, (DWORD) lpwfx->nAvgBytesPerSec);
}
// WavFormatMillesecondsToBytes - convert milleseconds to bytes
// <lpwfx> (i) pointer to WAVEFORMATEX struct
// <dwMilleseconds> (i) milleseconds
// return milleseconds
//
DWORD DLLEXPORT WINAPI WavFormatMillesecondsToBytes(LPWAVEFORMATEX lpwfx, DWORD dwMilleseconds)
{
if (lpwfx == NULL || lpwfx->nAvgBytesPerSec == 0)
return 0;
else
return MULDIVU32(dwMilleseconds, (DWORD) lpwfx->nAvgBytesPerSec, 1000);
}
// WavFormatSpeedAdjust - adjust format to reflect specified speed
// <lpwfx> (i/o) pointer to WAVEFORMATEX struct
// <nLevel> (i) speed level
// 50 half speed
// 100 normal speed
// 200 double speed, etc.
// <dwFlags> (i) reserved; must be zero
// return 0 if success
//
int DLLEXPORT WINAPI WavFormatSpeedAdjust(LPWAVEFORMATEX lpwfx, int nLevel, DWORD dwFlags)
{
BOOL fSuccess = TRUE;
if (lpwfx == NULL)
fSuccess = TraceFALSE(NULL);
else if (nLevel != 100)
{
lpwfx->nSamplesPerSec = lpwfx->nSamplesPerSec * nLevel / 100;
lpwfx->nAvgBytesPerSec = lpwfx->nBlockAlign * lpwfx->nSamplesPerSec;
}
return fSuccess ? 0 : -1;
}
// WavFormatVoxadpcm - fill WAVEFORMATEX struct for Dialogic OKI ADPCM
// <lpwfx> (o) pointer to output buffer
// NULL allocate new buffer to hold result
// <nSamplesPerSec> (i) sample rate
// -1 default sample rate (6000)
// return pointer to WAVEFORMATEX struct, NULL if error
//
// NOTE: if <lpwfx> points to a WAVEFORMATEX struct, this struct
// is filled in, and this function returns <lpwfx>.
// If <lpwfx> is NULL, space is dynamically allocated for the output
// buffer, and this function returns a pointer to the output buffer.
// Use WavFormatFree() to free the buffer.
//
LPWAVEFORMATEX DLLEXPORT WINAPI WavFormatVoxadpcm(LPWAVEFORMATEX lpwfx, long nSamplesPerSec)
{
BOOL fSuccess = TRUE;
LPWAVEFORMATEX lpwfxNew = lpwfx;
WORD nBitsPerSample = 4;
WORD nChannels = 1;
#if 0
// nBlockAlign is 4 so that chunk size of 5188 is returned from
// WavCalcChunkSize(VoxFormat(NULL, 6000), 1962, TRUE);
// 5188 is optimal for Dialogic buffer logic (((12 * 1024) - 512) / 2)
//
WORD nBlockAlign = 4;
#else
WORD nBlockAlign = 1;
#endif
if (nSamplesPerSec == -1)
nSamplesPerSec = 6000;
// user passed struct to fill
//
if (lpwfx != NULL && IsBadReadPtr(lpwfx, sizeof(WAVEFORMATEX)))
fSuccess = TraceFALSE(NULL);
// we allocate struct to fill
//
else if (lpwfx == NULL
&& (lpwfxNew = WavFormatAlloc(sizeof(WAVEFORMATEX))) == NULL)
fSuccess = TraceFALSE(NULL);
// fill the struct
//
else
{
lpwfxNew->wFormatTag = WAVE_FORMAT_DIALOGIC_OKI_ADPCM;
lpwfxNew->nChannels = nChannels;
lpwfxNew->nSamplesPerSec = nSamplesPerSec;
lpwfxNew->nBlockAlign = nBlockAlign;
lpwfxNew->nAvgBytesPerSec = nSamplesPerSec / 2;
lpwfxNew->wBitsPerSample = nBitsPerSample;
lpwfxNew->cbSize = 0;
}
return fSuccess ? lpwfxNew : NULL;
}
// WavFormatMulaw - fill WAVEFORMATEX struct for CCITT u-law format
// <lpwfx> (o) pointer to output buffer
// NULL allocate new buffer to hold result
// <nSamplesPerSec> (i) sample rate
// -1 default sample rate (8000)
// return pointer to WAVEFORMATEX struct, NULL if error
//
// NOTE: if <lpwfx> points to a WAVEFORMATEX struct, this struct
// is filled in, and this function returns <lpwfx>.
// If <lpwfx> is NULL, space is dynamically allocated for the output
// buffer, and this function returns a pointer to the output buffer.
// Use WavFormatFree() to free the buffer.
//
LPWAVEFORMATEX DLLEXPORT WINAPI WavFormatMulaw(LPWAVEFORMATEX lpwfx, long nSamplesPerSec)
{
BOOL fSuccess = TRUE;
LPWAVEFORMATEX lpwfxNew = lpwfx;
WORD nBitsPerSample = 8;
WORD nChannels = 1;
WORD nBlockAlign = 1;
if (nSamplesPerSec == -1)
nSamplesPerSec = 8000;
// user passed struct to fill
//
if (lpwfx != NULL && IsBadReadPtr(lpwfx, sizeof(WAVEFORMATEX)))
fSuccess = TraceFALSE(NULL);
// we allocate struct to fill
//
else if (lpwfx == NULL
&& (lpwfxNew = WavFormatAlloc(sizeof(WAVEFORMATEX))) == NULL)
fSuccess = TraceFALSE(NULL);
// fill the struct
//
else
{
lpwfxNew->wFormatTag = WAVE_FORMAT_MULAW;
lpwfxNew->nChannels = nChannels;
lpwfxNew->nSamplesPerSec = nSamplesPerSec;
lpwfxNew->nBlockAlign = nBlockAlign;
lpwfxNew->nAvgBytesPerSec = lpwfxNew->nBlockAlign * nSamplesPerSec;
lpwfxNew->wBitsPerSample = nBitsPerSample;
lpwfxNew->cbSize = 0;
}
return fSuccess ? lpwfxNew : NULL;
}
// WavFormatAlaw - fill WAVEFORMATEX struct for CCITT a-law format
// <lpwfx> (o) pointer to output buffer
// NULL allocate new buffer to hold result
// <nSamplesPerSec> (i) sample rate
// -1 default sample rate (8000)
// return pointer to WAVEFORMATEX struct, NULL if error
//
// NOTE: if <lpwfx> points to a WAVEFORMATEX struct, this struct
// is filled in, and this function returns <lpwfx>.
// If <lpwfx> is NULL, space is dynamically allocated for the output
// buffer, and this function returns a pointer to the output buffer.
// Use WavFormatFree() to free the buffer.
//
LPWAVEFORMATEX DLLEXPORT WINAPI WavFormatAlaw(LPWAVEFORMATEX lpwfx, long nSamplesPerSec)
{
BOOL fSuccess = TRUE;
LPWAVEFORMATEX lpwfxNew = lpwfx;
WORD nBitsPerSample = 8;
WORD nChannels = 1;
WORD nBlockAlign = 1;
if (nSamplesPerSec == -1)
nSamplesPerSec = 8000;
// user passed struct to fill
//
if (lpwfx != NULL && IsBadReadPtr(lpwfx, sizeof(WAVEFORMATEX)))
fSuccess = TraceFALSE(NULL);
// we allocate struct to fill
//
else if (lpwfx == NULL
&& (lpwfxNew = WavFormatAlloc(sizeof(WAVEFORMATEX))) == NULL)
fSuccess = TraceFALSE(NULL);
// fill the struct
//
else
{
lpwfxNew->wFormatTag = WAVE_FORMAT_ALAW;
lpwfxNew->nChannels = nChannels;
lpwfxNew->nSamplesPerSec = nSamplesPerSec;
lpwfxNew->nBlockAlign = nBlockAlign;
lpwfxNew->nAvgBytesPerSec = lpwfxNew->nBlockAlign * nSamplesPerSec;
lpwfxNew->wBitsPerSample = nBitsPerSample;
lpwfxNew->cbSize = 0;
}
return fSuccess ? lpwfxNew : NULL;
}