599 lines
16 KiB
C
599 lines
16 KiB
C
|
/***************************************************************************
|
||
|
*
|
||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
*
|
||
|
* File: xact3wb.h
|
||
|
* Content: XACT 3 wave bank definitions.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#ifndef __XACT3WB_H__
|
||
|
#define __XACT3WB_H__
|
||
|
|
||
|
#ifdef _XBOX
|
||
|
# include <xtl.h>
|
||
|
#else
|
||
|
# include <math.h>
|
||
|
#endif
|
||
|
|
||
|
#include <audiodefs.h>
|
||
|
#include <xma2defs.h>
|
||
|
|
||
|
#pragma warning(push)
|
||
|
#pragma warning(disable:4201)
|
||
|
#pragma warning(disable:4214) // nonstandard extension used : bit field types other than int
|
||
|
|
||
|
#pragma pack(push, 1)
|
||
|
#if !defined(_X86_)
|
||
|
#define XACTUNALIGNED __unaligned
|
||
|
#else
|
||
|
#define XACTUNALIGNED
|
||
|
#endif
|
||
|
|
||
|
#ifdef _M_PPCBE
|
||
|
#pragma bitfield_order(push, lsb_to_msb)
|
||
|
#endif
|
||
|
|
||
|
#define WAVEBANK_HEADER_SIGNATURE 'DNBW' // WaveBank RIFF chunk signature
|
||
|
#define WAVEBANK_HEADER_VERSION 44 // Current wavebank file version
|
||
|
|
||
|
#define WAVEBANK_BANKNAME_LENGTH 64 // Wave bank friendly name length, in characters
|
||
|
#define WAVEBANK_ENTRYNAME_LENGTH 64 // Wave bank entry friendly name length, in characters
|
||
|
|
||
|
#define WAVEBANK_MAX_DATA_SEGMENT_SIZE 0xFFFFFFFF // Maximum wave bank data segment size, in bytes
|
||
|
#define WAVEBANK_MAX_COMPACT_DATA_SEGMENT_SIZE 0x001FFFFF // Maximum compact wave bank data segment size, in bytes
|
||
|
|
||
|
typedef DWORD WAVEBANKOFFSET;
|
||
|
|
||
|
//
|
||
|
// Bank flags
|
||
|
//
|
||
|
|
||
|
#define WAVEBANK_TYPE_BUFFER 0x00000000 // In-memory buffer
|
||
|
#define WAVEBANK_TYPE_STREAMING 0x00000001 // Streaming
|
||
|
#define WAVEBANK_TYPE_MASK 0x00000001
|
||
|
|
||
|
#define WAVEBANK_FLAGS_ENTRYNAMES 0x00010000 // Bank includes entry names
|
||
|
#define WAVEBANK_FLAGS_COMPACT 0x00020000 // Bank uses compact format
|
||
|
#define WAVEBANK_FLAGS_SYNC_DISABLED 0x00040000 // Bank is disabled for audition sync
|
||
|
#define WAVEBANK_FLAGS_SEEKTABLES 0x00080000 // Bank includes seek tables.
|
||
|
#define WAVEBANK_FLAGS_MASK 0x000F0000
|
||
|
|
||
|
//
|
||
|
// Entry flags
|
||
|
//
|
||
|
|
||
|
#define WAVEBANKENTRY_FLAGS_READAHEAD 0x00000001 // Enable stream read-ahead
|
||
|
#define WAVEBANKENTRY_FLAGS_LOOPCACHE 0x00000002 // One or more looping sounds use this wave
|
||
|
#define WAVEBANKENTRY_FLAGS_REMOVELOOPTAIL 0x00000004 // Remove data after the end of the loop region
|
||
|
#define WAVEBANKENTRY_FLAGS_IGNORELOOP 0x00000008 // Used internally when the loop region can't be used
|
||
|
#define WAVEBANKENTRY_FLAGS_MASK 0x00000008
|
||
|
|
||
|
//
|
||
|
// Entry wave format identifiers
|
||
|
//
|
||
|
|
||
|
#define WAVEBANKMINIFORMAT_TAG_PCM 0x0 // PCM data
|
||
|
#define WAVEBANKMINIFORMAT_TAG_XMA 0x1 // XMA data
|
||
|
#define WAVEBANKMINIFORMAT_TAG_ADPCM 0x2 // ADPCM data
|
||
|
#define WAVEBANKMINIFORMAT_TAG_WMA 0x3 // WMA data
|
||
|
|
||
|
#define WAVEBANKMINIFORMAT_BITDEPTH_8 0x0 // 8-bit data (PCM only)
|
||
|
#define WAVEBANKMINIFORMAT_BITDEPTH_16 0x1 // 16-bit data (PCM only)
|
||
|
|
||
|
//
|
||
|
// Arbitrary fixed sizes
|
||
|
//
|
||
|
#define WAVEBANKENTRY_XMASTREAMS_MAX 3 // enough for 5.1 channel audio
|
||
|
#define WAVEBANKENTRY_XMACHANNELS_MAX 6 // enough for 5.1 channel audio (cf. XAUDIOCHANNEL_SOURCEMAX)
|
||
|
|
||
|
//
|
||
|
// DVD data sizes
|
||
|
//
|
||
|
|
||
|
#define WAVEBANK_DVD_SECTOR_SIZE 2048
|
||
|
#define WAVEBANK_DVD_BLOCK_SIZE (WAVEBANK_DVD_SECTOR_SIZE * 16)
|
||
|
|
||
|
//
|
||
|
// Bank alignment presets
|
||
|
//
|
||
|
|
||
|
#define WAVEBANK_ALIGNMENT_MIN 4 // Minimum alignment
|
||
|
#define WAVEBANK_ALIGNMENT_DVD WAVEBANK_DVD_SECTOR_SIZE // DVD-optimized alignment
|
||
|
|
||
|
//
|
||
|
// Wave bank segment identifiers
|
||
|
//
|
||
|
|
||
|
typedef enum WAVEBANKSEGIDX
|
||
|
{
|
||
|
WAVEBANK_SEGIDX_BANKDATA = 0, // Bank data
|
||
|
WAVEBANK_SEGIDX_ENTRYMETADATA, // Entry meta-data
|
||
|
WAVEBANK_SEGIDX_SEEKTABLES, // Storage for seek tables for the encoded waves.
|
||
|
WAVEBANK_SEGIDX_ENTRYNAMES, // Entry friendly names
|
||
|
WAVEBANK_SEGIDX_ENTRYWAVEDATA, // Entry wave data
|
||
|
WAVEBANK_SEGIDX_COUNT
|
||
|
} WAVEBANKSEGIDX, *LPWAVEBANKSEGIDX;
|
||
|
|
||
|
typedef const WAVEBANKSEGIDX *LPCWAVEBANKSEGIDX;
|
||
|
|
||
|
//
|
||
|
// Endianness
|
||
|
//
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
namespace XACTWaveBank
|
||
|
{
|
||
|
__inline void SwapBytes(XACTUNALIGNED DWORD &dw)
|
||
|
{
|
||
|
|
||
|
#ifdef _X86_
|
||
|
|
||
|
__asm
|
||
|
{
|
||
|
mov edi, dw
|
||
|
mov eax, [edi]
|
||
|
bswap eax
|
||
|
mov [edi], eax
|
||
|
}
|
||
|
|
||
|
#else // _X86_
|
||
|
|
||
|
dw = _byteswap_ulong(dw);
|
||
|
|
||
|
#endif // _X86_
|
||
|
|
||
|
}
|
||
|
|
||
|
__inline void SwapBytes(XACTUNALIGNED WORD &w)
|
||
|
{
|
||
|
|
||
|
#ifdef _X86_
|
||
|
|
||
|
__asm
|
||
|
{
|
||
|
mov edi, w
|
||
|
mov ax, [edi]
|
||
|
xchg ah, al
|
||
|
mov [edi], ax
|
||
|
}
|
||
|
|
||
|
#else // _X86_
|
||
|
|
||
|
w = _byteswap_ushort(w);
|
||
|
|
||
|
#endif // _X86_
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
//
|
||
|
// Wave bank region in bytes.
|
||
|
//
|
||
|
|
||
|
typedef struct WAVEBANKREGION
|
||
|
{
|
||
|
DWORD dwOffset; // Region offset, in bytes.
|
||
|
DWORD dwLength; // Region length, in bytes.
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
void SwapBytes(void)
|
||
|
{
|
||
|
XACTWaveBank::SwapBytes(dwOffset);
|
||
|
XACTWaveBank::SwapBytes(dwLength);
|
||
|
}
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
} WAVEBANKREGION, *LPWAVEBANKREGION;
|
||
|
|
||
|
typedef const WAVEBANKREGION *LPCWAVEBANKREGION;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Wave bank region in samples.
|
||
|
//
|
||
|
|
||
|
typedef struct WAVEBANKSAMPLEREGION
|
||
|
{
|
||
|
DWORD dwStartSample; // Start sample for the region.
|
||
|
DWORD dwTotalSamples; // Region length in samples.
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
void SwapBytes(void)
|
||
|
{
|
||
|
XACTWaveBank::SwapBytes(dwStartSample);
|
||
|
XACTWaveBank::SwapBytes(dwTotalSamples);
|
||
|
}
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
} WAVEBANKSAMPLEREGION, *LPWAVEBANKSAMPLEREGION;
|
||
|
|
||
|
typedef const WAVEBANKSAMPLEREGION *LPCWAVEBANKSAMPLEREGION;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Wave bank file header
|
||
|
//
|
||
|
|
||
|
typedef struct WAVEBANKHEADER
|
||
|
{
|
||
|
DWORD dwSignature; // File signature
|
||
|
DWORD dwVersion; // Version of the tool that created the file
|
||
|
DWORD dwHeaderVersion; // Version of the file format
|
||
|
WAVEBANKREGION Segments[WAVEBANK_SEGIDX_COUNT]; // Segment lookup table
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
void SwapBytes(void)
|
||
|
{
|
||
|
XACTWaveBank::SwapBytes(dwSignature);
|
||
|
XACTWaveBank::SwapBytes(dwVersion);
|
||
|
XACTWaveBank::SwapBytes(dwHeaderVersion);
|
||
|
|
||
|
for(int i = 0; i < WAVEBANK_SEGIDX_COUNT; i++)
|
||
|
{
|
||
|
Segments[i].SwapBytes();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
} WAVEBANKHEADER, *LPWAVEBANKHEADER;
|
||
|
|
||
|
typedef const WAVEBANKHEADER *LPCWAVEBANKHEADER;
|
||
|
|
||
|
//
|
||
|
// Table for converting WMA Average Bytes per Second values to the WAVEBANKMINIWAVEFORMAT wBlockAlign field
|
||
|
// NOTE: There can be a max of 8 values in the table.
|
||
|
//
|
||
|
|
||
|
#define MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES 7
|
||
|
|
||
|
static const DWORD aWMAAvgBytesPerSec[] =
|
||
|
{
|
||
|
12000,
|
||
|
24000,
|
||
|
4000,
|
||
|
6000,
|
||
|
8000,
|
||
|
20000,
|
||
|
2500
|
||
|
};
|
||
|
// bitrate = entry * 8
|
||
|
|
||
|
//
|
||
|
// Table for converting WMA Block Align values to the WAVEBANKMINIWAVEFORMAT wBlockAlign field
|
||
|
// NOTE: There can be a max of 32 values in the table.
|
||
|
//
|
||
|
|
||
|
#define MAX_WMA_BLOCK_ALIGN_ENTRIES 17
|
||
|
|
||
|
static const DWORD aWMABlockAlign[] =
|
||
|
{
|
||
|
929,
|
||
|
1487,
|
||
|
1280,
|
||
|
2230,
|
||
|
8917,
|
||
|
8192,
|
||
|
4459,
|
||
|
5945,
|
||
|
2304,
|
||
|
1536,
|
||
|
1485,
|
||
|
1008,
|
||
|
2731,
|
||
|
4096,
|
||
|
6827,
|
||
|
5462,
|
||
|
1280
|
||
|
};
|
||
|
|
||
|
struct WAVEBANKENTRY;
|
||
|
|
||
|
//
|
||
|
// Entry compressed data format
|
||
|
//
|
||
|
|
||
|
typedef union WAVEBANKMINIWAVEFORMAT
|
||
|
{
|
||
|
struct
|
||
|
{
|
||
|
DWORD wFormatTag : 2; // Format tag
|
||
|
DWORD nChannels : 3; // Channel count (1 - 6)
|
||
|
DWORD nSamplesPerSec : 18; // Sampling rate
|
||
|
DWORD wBlockAlign : 8; // Block alignment. For WMA, lower 6 bits block alignment index, upper 2 bits bytes-per-second index.
|
||
|
DWORD wBitsPerSample : 1; // Bits per sample (8 vs. 16, PCM only); WMAudio2/WMAudio3 (for WMA)
|
||
|
};
|
||
|
|
||
|
DWORD dwValue;
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
void SwapBytes(void)
|
||
|
{
|
||
|
XACTWaveBank::SwapBytes(dwValue);
|
||
|
}
|
||
|
|
||
|
WORD BitsPerSample() const
|
||
|
{
|
||
|
if (wFormatTag == WAVEBANKMINIFORMAT_TAG_XMA)
|
||
|
return XMA_OUTPUT_SAMPLE_BITS; // First, because most common on Xbox 360
|
||
|
if (wFormatTag == WAVEBANKMINIFORMAT_TAG_WMA)
|
||
|
return 16;
|
||
|
if (wFormatTag == WAVEBANKMINIFORMAT_TAG_ADPCM)
|
||
|
return 4; // MSADPCM_BITS_PER_SAMPLE == 4
|
||
|
|
||
|
// wFormatTag must be WAVEBANKMINIFORMAT_TAG_PCM (2 bits can only represent 4 different values)
|
||
|
return (wBitsPerSample == WAVEBANKMINIFORMAT_BITDEPTH_16) ? 16 : 8;
|
||
|
}
|
||
|
|
||
|
#define ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET 22
|
||
|
DWORD BlockAlign() const
|
||
|
{
|
||
|
DWORD dwReturn = 0;
|
||
|
|
||
|
switch (wFormatTag)
|
||
|
{
|
||
|
case WAVEBANKMINIFORMAT_TAG_PCM:
|
||
|
dwReturn = wBlockAlign;
|
||
|
break;
|
||
|
|
||
|
case WAVEBANKMINIFORMAT_TAG_XMA:
|
||
|
dwReturn = nChannels * XMA_OUTPUT_SAMPLE_BITS / 8;
|
||
|
break;
|
||
|
|
||
|
case WAVEBANKMINIFORMAT_TAG_ADPCM:
|
||
|
dwReturn = (wBlockAlign + ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET) * nChannels;
|
||
|
break;
|
||
|
|
||
|
case WAVEBANKMINIFORMAT_TAG_WMA:
|
||
|
{
|
||
|
DWORD dwBlockAlignIndex = wBlockAlign & 0x1F;
|
||
|
if (dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES)
|
||
|
dwReturn = aWMABlockAlign[dwBlockAlignIndex];
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
DWORD AvgBytesPerSec() const
|
||
|
{
|
||
|
DWORD dwReturn = 0;
|
||
|
|
||
|
switch (wFormatTag)
|
||
|
{
|
||
|
case WAVEBANKMINIFORMAT_TAG_PCM:
|
||
|
case WAVEBANKMINIFORMAT_TAG_XMA:
|
||
|
dwReturn = nSamplesPerSec * wBlockAlign;
|
||
|
break;
|
||
|
|
||
|
case WAVEBANKMINIFORMAT_TAG_ADPCM:
|
||
|
{
|
||
|
DWORD blockAlign = BlockAlign();
|
||
|
DWORD samplesPerAdpcmBlock = AdpcmSamplesPerBlock();
|
||
|
dwReturn = blockAlign * nSamplesPerSec / samplesPerAdpcmBlock;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WAVEBANKMINIFORMAT_TAG_WMA:
|
||
|
{
|
||
|
DWORD dwBytesPerSecIndex = wBlockAlign >> 5;
|
||
|
if (dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES)
|
||
|
dwReturn = aWMAAvgBytesPerSec[dwBytesPerSecIndex];
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
DWORD EncodeWMABlockAlign(DWORD dwBlockAlign, DWORD dwAvgBytesPerSec) const
|
||
|
{
|
||
|
DWORD dwReturn = 0;
|
||
|
DWORD dwBlockAlignIndex = 0;
|
||
|
DWORD dwBytesPerSecIndex = 0;
|
||
|
|
||
|
for (; dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES && dwBlockAlign != aWMABlockAlign[dwBlockAlignIndex]; dwBlockAlignIndex++);
|
||
|
|
||
|
if (dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES)
|
||
|
{
|
||
|
for (; dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES && dwAvgBytesPerSec != aWMAAvgBytesPerSec[dwBytesPerSecIndex]; dwBytesPerSecIndex++);
|
||
|
|
||
|
if (dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES)
|
||
|
{
|
||
|
dwReturn = dwBlockAlignIndex | (dwBytesPerSecIndex << 5);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return dwReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
void XMA2FillFormatEx(XMA2WAVEFORMATEX *fmt, WORD blockCount, const struct WAVEBANKENTRY* entry) const;
|
||
|
|
||
|
DWORD AdpcmSamplesPerBlock() const
|
||
|
{
|
||
|
DWORD nBlockAlign = (wBlockAlign + ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET) * nChannels;
|
||
|
return nBlockAlign * 2 / (DWORD)nChannels - 12;
|
||
|
}
|
||
|
|
||
|
void AdpcmFillCoefficientTable(ADPCMWAVEFORMAT *fmt) const
|
||
|
{
|
||
|
// These are fixed since we are always using MS ADPCM
|
||
|
fmt->wNumCoef = 7; /* MSADPCM_NUM_COEFFICIENTS */
|
||
|
|
||
|
static ADPCMCOEFSET aCoef[7] = { { 256, 0}, {512, -256}, {0,0}, {192,64}, {240,0}, {460, -208}, {392,-232} };
|
||
|
memcpy( &fmt->aCoef, aCoef, sizeof(aCoef) );
|
||
|
}
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
} WAVEBANKMINIWAVEFORMAT, *LPWAVEBANKMINIWAVEFORMAT;
|
||
|
|
||
|
typedef const WAVEBANKMINIWAVEFORMAT *LPCWAVEBANKMINIWAVEFORMAT;
|
||
|
|
||
|
//
|
||
|
// Entry meta-data
|
||
|
//
|
||
|
|
||
|
typedef struct WAVEBANKENTRY
|
||
|
{
|
||
|
union
|
||
|
{
|
||
|
struct
|
||
|
{
|
||
|
// Entry flags
|
||
|
DWORD dwFlags : 4;
|
||
|
|
||
|
// Duration of the wave, in units of one sample.
|
||
|
// For instance, a ten second long wave sampled
|
||
|
// at 48KHz would have a duration of 480,000.
|
||
|
// This value is not affected by the number of
|
||
|
// channels, the number of bits per sample, or the
|
||
|
// compression format of the wave.
|
||
|
DWORD Duration : 28;
|
||
|
};
|
||
|
DWORD dwFlagsAndDuration;
|
||
|
};
|
||
|
|
||
|
WAVEBANKMINIWAVEFORMAT Format; // Entry format.
|
||
|
WAVEBANKREGION PlayRegion; // Region within the wave data segment that contains this entry.
|
||
|
WAVEBANKSAMPLEREGION LoopRegion; // Region within the wave data (in samples) that should loop.
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
void SwapBytes(void)
|
||
|
{
|
||
|
XACTWaveBank::SwapBytes(dwFlagsAndDuration);
|
||
|
Format.SwapBytes();
|
||
|
PlayRegion.SwapBytes();
|
||
|
LoopRegion.SwapBytes();
|
||
|
}
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
} WAVEBANKENTRY, *LPWAVEBANKENTRY;
|
||
|
|
||
|
typedef const WAVEBANKENTRY *LPCWAVEBANKENTRY;
|
||
|
|
||
|
//
|
||
|
// Compact entry meta-data
|
||
|
//
|
||
|
|
||
|
typedef struct WAVEBANKENTRYCOMPACT
|
||
|
{
|
||
|
DWORD dwOffset : 21; // Data offset, in sectors
|
||
|
DWORD dwLengthDeviation : 11; // Data length deviation, in bytes
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
void SwapBytes(void)
|
||
|
{
|
||
|
XACTWaveBank::SwapBytes(*(LPDWORD)this);
|
||
|
}
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
} WAVEBANKENTRYCOMPACT, *LPWAVEBANKENTRYCOMPACT;
|
||
|
|
||
|
typedef const WAVEBANKENTRYCOMPACT *LPCWAVEBANKENTRYCOMPACT;
|
||
|
|
||
|
//
|
||
|
// Bank data segment
|
||
|
//
|
||
|
|
||
|
typedef struct WAVEBANKDATA
|
||
|
{
|
||
|
DWORD dwFlags; // Bank flags
|
||
|
DWORD dwEntryCount; // Number of entries in the bank
|
||
|
CHAR szBankName[WAVEBANK_BANKNAME_LENGTH]; // Bank friendly name
|
||
|
DWORD dwEntryMetaDataElementSize; // Size of each entry meta-data element, in bytes
|
||
|
DWORD dwEntryNameElementSize; // Size of each entry name element, in bytes
|
||
|
DWORD dwAlignment; // Entry alignment, in bytes
|
||
|
WAVEBANKMINIWAVEFORMAT CompactFormat; // Format data for compact bank
|
||
|
FILETIME BuildTime; // Build timestamp
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
|
||
|
void SwapBytes(void)
|
||
|
{
|
||
|
XACTWaveBank::SwapBytes(dwFlags);
|
||
|
XACTWaveBank::SwapBytes(dwEntryCount);
|
||
|
XACTWaveBank::SwapBytes(dwEntryMetaDataElementSize);
|
||
|
XACTWaveBank::SwapBytes(dwEntryNameElementSize);
|
||
|
XACTWaveBank::SwapBytes(dwAlignment);
|
||
|
CompactFormat.SwapBytes();
|
||
|
XACTWaveBank::SwapBytes(BuildTime.dwLowDateTime);
|
||
|
XACTWaveBank::SwapBytes(BuildTime.dwHighDateTime);
|
||
|
}
|
||
|
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
} WAVEBANKDATA, *LPWAVEBANKDATA;
|
||
|
|
||
|
typedef const WAVEBANKDATA *LPCWAVEBANKDATA;
|
||
|
|
||
|
inline void WAVEBANKMINIWAVEFORMAT::XMA2FillFormatEx(XMA2WAVEFORMATEX *fmt, WORD blockCount, const WAVEBANKENTRY* entry) const
|
||
|
{
|
||
|
// Note caller is responsbile for filling out fmt->wfx with other helper functions.
|
||
|
|
||
|
fmt->NumStreams = (WORD)( (nChannels + 1) / 2 );
|
||
|
|
||
|
switch (nChannels)
|
||
|
{
|
||
|
case 1: fmt->ChannelMask = SPEAKER_MONO; break;
|
||
|
case 2: fmt->ChannelMask = SPEAKER_STEREO; break;
|
||
|
case 3: fmt->ChannelMask = SPEAKER_2POINT1; break;
|
||
|
case 4: fmt->ChannelMask = SPEAKER_QUAD; break;
|
||
|
case 5: fmt->ChannelMask = SPEAKER_4POINT1; break;
|
||
|
case 6: fmt->ChannelMask = SPEAKER_5POINT1; break;
|
||
|
case 7: fmt->ChannelMask = SPEAKER_5POINT1 | SPEAKER_BACK_CENTER; break;
|
||
|
case 8: fmt->ChannelMask = SPEAKER_7POINT1; break;
|
||
|
default: fmt->ChannelMask = 0; break;
|
||
|
}
|
||
|
|
||
|
fmt->SamplesEncoded = entry->Duration;
|
||
|
fmt->BytesPerBlock = 65536; /* XACT_FIXED_XMA_BLOCK_SIZE */
|
||
|
|
||
|
fmt->PlayBegin = entry->PlayRegion.dwOffset;
|
||
|
fmt->PlayLength = entry->PlayRegion.dwLength;
|
||
|
|
||
|
if (entry->LoopRegion.dwTotalSamples > 0)
|
||
|
{
|
||
|
fmt->LoopBegin = entry->LoopRegion.dwStartSample;
|
||
|
fmt->LoopLength = entry->LoopRegion.dwTotalSamples;
|
||
|
fmt->LoopCount = 0xff; /* XACTLOOPCOUNT_INFINITE */
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fmt->LoopBegin = 0;
|
||
|
fmt->LoopLength = 0;
|
||
|
fmt->LoopCount = 0;
|
||
|
}
|
||
|
|
||
|
fmt->EncoderVersion = 4; // XMAENCODER_VERSION_XMA2
|
||
|
|
||
|
fmt->BlockCount = blockCount;
|
||
|
}
|
||
|
|
||
|
#ifdef _M_PPCBE
|
||
|
#pragma bitfield_order(pop)
|
||
|
#endif
|
||
|
|
||
|
#pragma warning(pop)
|
||
|
#pragma pack(pop)
|
||
|
|
||
|
#endif // __XACTWB_H__
|
||
|
|