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
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;
|
|
}
|