Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | /*************************************************************************** |
| 2 | * |
||
| 3 | * Copyright (c) Microsoft Corporation. All rights reserved. |
||
| 4 | * |
||
| 5 | * File: xact3wb.h |
||
| 6 | * Content: XACT 3 wave bank definitions. |
||
| 7 | * |
||
| 8 | ****************************************************************************/ |
||
| 9 | |||
| 10 | #ifndef __XACT3WB_H__ |
||
| 11 | #define __XACT3WB_H__ |
||
| 12 | |||
| 13 | #ifdef _XBOX |
||
| 14 | # include <xtl.h> |
||
| 15 | #else |
||
| 16 | # include <math.h> |
||
| 17 | #endif |
||
| 18 | |||
| 19 | #include <audiodefs.h> |
||
| 20 | #include <xma2defs.h> |
||
| 21 | |||
| 22 | #pragma warning(push) |
||
| 23 | #pragma warning(disable:4201) |
||
| 24 | #pragma warning(disable:4214) // nonstandard extension used : bit field types other than int |
||
| 25 | |||
| 26 | #pragma pack(push, 1) |
||
| 27 | #if !defined(_X86_) |
||
| 28 | #define XACTUNALIGNED __unaligned |
||
| 29 | #else |
||
| 30 | #define XACTUNALIGNED |
||
| 31 | #endif |
||
| 32 | |||
| 33 | #ifdef _M_PPCBE |
||
| 34 | #pragma bitfield_order(push, lsb_to_msb) |
||
| 35 | #endif |
||
| 36 | |||
| 37 | #define WAVEBANK_HEADER_SIGNATURE 'DNBW' // WaveBank RIFF chunk signature |
||
| 38 | #define WAVEBANK_HEADER_VERSION 44 // Current wavebank file version |
||
| 39 | |||
| 40 | #define WAVEBANK_BANKNAME_LENGTH 64 // Wave bank friendly name length, in characters |
||
| 41 | #define WAVEBANK_ENTRYNAME_LENGTH 64 // Wave bank entry friendly name length, in characters |
||
| 42 | |||
| 43 | #define WAVEBANK_MAX_DATA_SEGMENT_SIZE 0xFFFFFFFF // Maximum wave bank data segment size, in bytes |
||
| 44 | #define WAVEBANK_MAX_COMPACT_DATA_SEGMENT_SIZE 0x001FFFFF // Maximum compact wave bank data segment size, in bytes |
||
| 45 | |||
| 46 | typedef DWORD WAVEBANKOFFSET; |
||
| 47 | |||
| 48 | // |
||
| 49 | // Bank flags |
||
| 50 | // |
||
| 51 | |||
| 52 | #define WAVEBANK_TYPE_BUFFER 0x00000000 // In-memory buffer |
||
| 53 | #define WAVEBANK_TYPE_STREAMING 0x00000001 // Streaming |
||
| 54 | #define WAVEBANK_TYPE_MASK 0x00000001 |
||
| 55 | |||
| 56 | #define WAVEBANK_FLAGS_ENTRYNAMES 0x00010000 // Bank includes entry names |
||
| 57 | #define WAVEBANK_FLAGS_COMPACT 0x00020000 // Bank uses compact format |
||
| 58 | #define WAVEBANK_FLAGS_SYNC_DISABLED 0x00040000 // Bank is disabled for audition sync |
||
| 59 | #define WAVEBANK_FLAGS_SEEKTABLES 0x00080000 // Bank includes seek tables. |
||
| 60 | #define WAVEBANK_FLAGS_MASK 0x000F0000 |
||
| 61 | |||
| 62 | // |
||
| 63 | // Entry flags |
||
| 64 | // |
||
| 65 | |||
| 66 | #define WAVEBANKENTRY_FLAGS_READAHEAD 0x00000001 // Enable stream read-ahead |
||
| 67 | #define WAVEBANKENTRY_FLAGS_LOOPCACHE 0x00000002 // One or more looping sounds use this wave |
||
| 68 | #define WAVEBANKENTRY_FLAGS_REMOVELOOPTAIL 0x00000004 // Remove data after the end of the loop region |
||
| 69 | #define WAVEBANKENTRY_FLAGS_IGNORELOOP 0x00000008 // Used internally when the loop region can't be used |
||
| 70 | #define WAVEBANKENTRY_FLAGS_MASK 0x00000008 |
||
| 71 | |||
| 72 | // |
||
| 73 | // Entry wave format identifiers |
||
| 74 | // |
||
| 75 | |||
| 76 | #define WAVEBANKMINIFORMAT_TAG_PCM 0x0 // PCM data |
||
| 77 | #define WAVEBANKMINIFORMAT_TAG_XMA 0x1 // XMA data |
||
| 78 | #define WAVEBANKMINIFORMAT_TAG_ADPCM 0x2 // ADPCM data |
||
| 79 | #define WAVEBANKMINIFORMAT_TAG_WMA 0x3 // WMA data |
||
| 80 | |||
| 81 | #define WAVEBANKMINIFORMAT_BITDEPTH_8 0x0 // 8-bit data (PCM only) |
||
| 82 | #define WAVEBANKMINIFORMAT_BITDEPTH_16 0x1 // 16-bit data (PCM only) |
||
| 83 | |||
| 84 | // |
||
| 85 | // Arbitrary fixed sizes |
||
| 86 | // |
||
| 87 | #define WAVEBANKENTRY_XMASTREAMS_MAX 3 // enough for 5.1 channel audio |
||
| 88 | #define WAVEBANKENTRY_XMACHANNELS_MAX 6 // enough for 5.1 channel audio (cf. XAUDIOCHANNEL_SOURCEMAX) |
||
| 89 | |||
| 90 | // |
||
| 91 | // DVD data sizes |
||
| 92 | // |
||
| 93 | |||
| 94 | #define WAVEBANK_DVD_SECTOR_SIZE 2048 |
||
| 95 | #define WAVEBANK_DVD_BLOCK_SIZE (WAVEBANK_DVD_SECTOR_SIZE * 16) |
||
| 96 | |||
| 97 | // |
||
| 98 | // Bank alignment presets |
||
| 99 | // |
||
| 100 | |||
| 101 | #define WAVEBANK_ALIGNMENT_MIN 4 // Minimum alignment |
||
| 102 | #define WAVEBANK_ALIGNMENT_DVD WAVEBANK_DVD_SECTOR_SIZE // DVD-optimized alignment |
||
| 103 | |||
| 104 | // |
||
| 105 | // Wave bank segment identifiers |
||
| 106 | // |
||
| 107 | |||
| 108 | typedef enum WAVEBANKSEGIDX |
||
| 109 | { |
||
| 110 | WAVEBANK_SEGIDX_BANKDATA = 0, // Bank data |
||
| 111 | WAVEBANK_SEGIDX_ENTRYMETADATA, // Entry meta-data |
||
| 112 | WAVEBANK_SEGIDX_SEEKTABLES, // Storage for seek tables for the encoded waves. |
||
| 113 | WAVEBANK_SEGIDX_ENTRYNAMES, // Entry friendly names |
||
| 114 | WAVEBANK_SEGIDX_ENTRYWAVEDATA, // Entry wave data |
||
| 115 | WAVEBANK_SEGIDX_COUNT |
||
| 116 | } WAVEBANKSEGIDX, *LPWAVEBANKSEGIDX; |
||
| 117 | |||
| 118 | typedef const WAVEBANKSEGIDX *LPCWAVEBANKSEGIDX; |
||
| 119 | |||
| 120 | // |
||
| 121 | // Endianness |
||
| 122 | // |
||
| 123 | |||
| 124 | #ifdef __cplusplus |
||
| 125 | |||
| 126 | namespace XACTWaveBank |
||
| 127 | { |
||
| 128 | __inline void SwapBytes(XACTUNALIGNED DWORD &dw) |
||
| 129 | { |
||
| 130 | |||
| 131 | #ifdef _X86_ |
||
| 132 | |||
| 133 | __asm |
||
| 134 | { |
||
| 135 | mov edi, dw |
||
| 136 | mov eax, [edi] |
||
| 137 | bswap eax |
||
| 138 | mov [edi], eax |
||
| 139 | } |
||
| 140 | |||
| 141 | #else // _X86_ |
||
| 142 | |||
| 143 | dw = _byteswap_ulong(dw); |
||
| 144 | |||
| 145 | #endif // _X86_ |
||
| 146 | |||
| 147 | } |
||
| 148 | |||
| 149 | __inline void SwapBytes(XACTUNALIGNED WORD &w) |
||
| 150 | { |
||
| 151 | |||
| 152 | #ifdef _X86_ |
||
| 153 | |||
| 154 | __asm |
||
| 155 | { |
||
| 156 | mov edi, w |
||
| 157 | mov ax, [edi] |
||
| 158 | xchg ah, al |
||
| 159 | mov [edi], ax |
||
| 160 | } |
||
| 161 | |||
| 162 | #else // _X86_ |
||
| 163 | |||
| 164 | w = _byteswap_ushort(w); |
||
| 165 | |||
| 166 | #endif // _X86_ |
||
| 167 | |||
| 168 | } |
||
| 169 | |||
| 170 | } |
||
| 171 | |||
| 172 | #endif // __cplusplus |
||
| 173 | |||
| 174 | // |
||
| 175 | // Wave bank region in bytes. |
||
| 176 | // |
||
| 177 | |||
| 178 | typedef struct WAVEBANKREGION |
||
| 179 | { |
||
| 180 | DWORD dwOffset; // Region offset, in bytes. |
||
| 181 | DWORD dwLength; // Region length, in bytes. |
||
| 182 | |||
| 183 | #ifdef __cplusplus |
||
| 184 | |||
| 185 | void SwapBytes(void) |
||
| 186 | { |
||
| 187 | XACTWaveBank::SwapBytes(dwOffset); |
||
| 188 | XACTWaveBank::SwapBytes(dwLength); |
||
| 189 | } |
||
| 190 | |||
| 191 | #endif // __cplusplus |
||
| 192 | |||
| 193 | } WAVEBANKREGION, *LPWAVEBANKREGION; |
||
| 194 | |||
| 195 | typedef const WAVEBANKREGION *LPCWAVEBANKREGION; |
||
| 196 | |||
| 197 | |||
| 198 | // |
||
| 199 | // Wave bank region in samples. |
||
| 200 | // |
||
| 201 | |||
| 202 | typedef struct WAVEBANKSAMPLEREGION |
||
| 203 | { |
||
| 204 | DWORD dwStartSample; // Start sample for the region. |
||
| 205 | DWORD dwTotalSamples; // Region length in samples. |
||
| 206 | |||
| 207 | #ifdef __cplusplus |
||
| 208 | |||
| 209 | void SwapBytes(void) |
||
| 210 | { |
||
| 211 | XACTWaveBank::SwapBytes(dwStartSample); |
||
| 212 | XACTWaveBank::SwapBytes(dwTotalSamples); |
||
| 213 | } |
||
| 214 | |||
| 215 | #endif // __cplusplus |
||
| 216 | |||
| 217 | } WAVEBANKSAMPLEREGION, *LPWAVEBANKSAMPLEREGION; |
||
| 218 | |||
| 219 | typedef const WAVEBANKSAMPLEREGION *LPCWAVEBANKSAMPLEREGION; |
||
| 220 | |||
| 221 | |||
| 222 | // |
||
| 223 | // Wave bank file header |
||
| 224 | // |
||
| 225 | |||
| 226 | typedef struct WAVEBANKHEADER |
||
| 227 | { |
||
| 228 | DWORD dwSignature; // File signature |
||
| 229 | DWORD dwVersion; // Version of the tool that created the file |
||
| 230 | DWORD dwHeaderVersion; // Version of the file format |
||
| 231 | WAVEBANKREGION Segments[WAVEBANK_SEGIDX_COUNT]; // Segment lookup table |
||
| 232 | |||
| 233 | #ifdef __cplusplus |
||
| 234 | |||
| 235 | void SwapBytes(void) |
||
| 236 | { |
||
| 237 | XACTWaveBank::SwapBytes(dwSignature); |
||
| 238 | XACTWaveBank::SwapBytes(dwVersion); |
||
| 239 | XACTWaveBank::SwapBytes(dwHeaderVersion); |
||
| 240 | |||
| 241 | for(int i = 0; i < WAVEBANK_SEGIDX_COUNT; i++) |
||
| 242 | { |
||
| 243 | Segments[i].SwapBytes(); |
||
| 244 | } |
||
| 245 | } |
||
| 246 | |||
| 247 | #endif // __cplusplus |
||
| 248 | |||
| 249 | } WAVEBANKHEADER, *LPWAVEBANKHEADER; |
||
| 250 | |||
| 251 | typedef const WAVEBANKHEADER *LPCWAVEBANKHEADER; |
||
| 252 | |||
| 253 | // |
||
| 254 | // Table for converting WMA Average Bytes per Second values to the WAVEBANKMINIWAVEFORMAT wBlockAlign field |
||
| 255 | // NOTE: There can be a max of 8 values in the table. |
||
| 256 | // |
||
| 257 | |||
| 258 | #define MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES 7 |
||
| 259 | |||
| 260 | static const DWORD aWMAAvgBytesPerSec[] = |
||
| 261 | { |
||
| 262 | 12000, |
||
| 263 | 24000, |
||
| 264 | 4000, |
||
| 265 | 6000, |
||
| 266 | 8000, |
||
| 267 | 20000, |
||
| 268 | 2500 |
||
| 269 | }; |
||
| 270 | // bitrate = entry * 8 |
||
| 271 | |||
| 272 | // |
||
| 273 | // Table for converting WMA Block Align values to the WAVEBANKMINIWAVEFORMAT wBlockAlign field |
||
| 274 | // NOTE: There can be a max of 32 values in the table. |
||
| 275 | // |
||
| 276 | |||
| 277 | #define MAX_WMA_BLOCK_ALIGN_ENTRIES 17 |
||
| 278 | |||
| 279 | static const DWORD aWMABlockAlign[] = |
||
| 280 | { |
||
| 281 | 929, |
||
| 282 | 1487, |
||
| 283 | 1280, |
||
| 284 | 2230, |
||
| 285 | 8917, |
||
| 286 | 8192, |
||
| 287 | 4459, |
||
| 288 | 5945, |
||
| 289 | 2304, |
||
| 290 | 1536, |
||
| 291 | 1485, |
||
| 292 | 1008, |
||
| 293 | 2731, |
||
| 294 | 4096, |
||
| 295 | 6827, |
||
| 296 | 5462, |
||
| 297 | 1280 |
||
| 298 | }; |
||
| 299 | |||
| 300 | struct WAVEBANKENTRY; |
||
| 301 | |||
| 302 | // |
||
| 303 | // Entry compressed data format |
||
| 304 | // |
||
| 305 | |||
| 306 | typedef union WAVEBANKMINIWAVEFORMAT |
||
| 307 | { |
||
| 308 | struct |
||
| 309 | { |
||
| 310 | DWORD wFormatTag : 2; // Format tag |
||
| 311 | DWORD nChannels : 3; // Channel count (1 - 6) |
||
| 312 | DWORD nSamplesPerSec : 18; // Sampling rate |
||
| 313 | DWORD wBlockAlign : 8; // Block alignment. For WMA, lower 6 bits block alignment index, upper 2 bits bytes-per-second index. |
||
| 314 | DWORD wBitsPerSample : 1; // Bits per sample (8 vs. 16, PCM only); WMAudio2/WMAudio3 (for WMA) |
||
| 315 | }; |
||
| 316 | |||
| 317 | DWORD dwValue; |
||
| 318 | |||
| 319 | #ifdef __cplusplus |
||
| 320 | |||
| 321 | void SwapBytes(void) |
||
| 322 | { |
||
| 323 | XACTWaveBank::SwapBytes(dwValue); |
||
| 324 | } |
||
| 325 | |||
| 326 | WORD BitsPerSample() const |
||
| 327 | { |
||
| 328 | if (wFormatTag == WAVEBANKMINIFORMAT_TAG_XMA) |
||
| 329 | return XMA_OUTPUT_SAMPLE_BITS; // First, because most common on Xbox 360 |
||
| 330 | if (wFormatTag == WAVEBANKMINIFORMAT_TAG_WMA) |
||
| 331 | return 16; |
||
| 332 | if (wFormatTag == WAVEBANKMINIFORMAT_TAG_ADPCM) |
||
| 333 | return 4; // MSADPCM_BITS_PER_SAMPLE == 4 |
||
| 334 | |||
| 335 | // wFormatTag must be WAVEBANKMINIFORMAT_TAG_PCM (2 bits can only represent 4 different values) |
||
| 336 | return (wBitsPerSample == WAVEBANKMINIFORMAT_BITDEPTH_16) ? 16 : 8; |
||
| 337 | } |
||
| 338 | |||
| 339 | #define ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET 22 |
||
| 340 | DWORD BlockAlign() const |
||
| 341 | { |
||
| 342 | DWORD dwReturn = 0; |
||
| 343 | |||
| 344 | switch (wFormatTag) |
||
| 345 | { |
||
| 346 | case WAVEBANKMINIFORMAT_TAG_PCM: |
||
| 347 | dwReturn = wBlockAlign; |
||
| 348 | break; |
||
| 349 | |||
| 350 | case WAVEBANKMINIFORMAT_TAG_XMA: |
||
| 351 | dwReturn = nChannels * XMA_OUTPUT_SAMPLE_BITS / 8; |
||
| 352 | break; |
||
| 353 | |||
| 354 | case WAVEBANKMINIFORMAT_TAG_ADPCM: |
||
| 355 | dwReturn = (wBlockAlign + ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET) * nChannels; |
||
| 356 | break; |
||
| 357 | |||
| 358 | case WAVEBANKMINIFORMAT_TAG_WMA: |
||
| 359 | { |
||
| 360 | DWORD dwBlockAlignIndex = wBlockAlign & 0x1F; |
||
| 361 | if (dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES) |
||
| 362 | dwReturn = aWMABlockAlign[dwBlockAlignIndex]; |
||
| 363 | } |
||
| 364 | break; |
||
| 365 | } |
||
| 366 | |||
| 367 | return dwReturn; |
||
| 368 | } |
||
| 369 | |||
| 370 | DWORD AvgBytesPerSec() const |
||
| 371 | { |
||
| 372 | DWORD dwReturn = 0; |
||
| 373 | |||
| 374 | switch (wFormatTag) |
||
| 375 | { |
||
| 376 | case WAVEBANKMINIFORMAT_TAG_PCM: |
||
| 377 | case WAVEBANKMINIFORMAT_TAG_XMA: |
||
| 378 | dwReturn = nSamplesPerSec * wBlockAlign; |
||
| 379 | break; |
||
| 380 | |||
| 381 | case WAVEBANKMINIFORMAT_TAG_ADPCM: |
||
| 382 | { |
||
| 383 | DWORD blockAlign = BlockAlign(); |
||
| 384 | DWORD samplesPerAdpcmBlock = AdpcmSamplesPerBlock(); |
||
| 385 | dwReturn = blockAlign * nSamplesPerSec / samplesPerAdpcmBlock; |
||
| 386 | } |
||
| 387 | break; |
||
| 388 | |||
| 389 | case WAVEBANKMINIFORMAT_TAG_WMA: |
||
| 390 | { |
||
| 391 | DWORD dwBytesPerSecIndex = wBlockAlign >> 5; |
||
| 392 | if (dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES) |
||
| 393 | dwReturn = aWMAAvgBytesPerSec[dwBytesPerSecIndex]; |
||
| 394 | } |
||
| 395 | break; |
||
| 396 | } |
||
| 397 | |||
| 398 | return dwReturn; |
||
| 399 | } |
||
| 400 | |||
| 401 | DWORD EncodeWMABlockAlign(DWORD dwBlockAlign, DWORD dwAvgBytesPerSec) const |
||
| 402 | { |
||
| 403 | DWORD dwReturn = 0; |
||
| 404 | DWORD dwBlockAlignIndex = 0; |
||
| 405 | DWORD dwBytesPerSecIndex = 0; |
||
| 406 | |||
| 407 | for (; dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES && dwBlockAlign != aWMABlockAlign[dwBlockAlignIndex]; dwBlockAlignIndex++); |
||
| 408 | |||
| 409 | if (dwBlockAlignIndex < MAX_WMA_BLOCK_ALIGN_ENTRIES) |
||
| 410 | { |
||
| 411 | for (; dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES && dwAvgBytesPerSec != aWMAAvgBytesPerSec[dwBytesPerSecIndex]; dwBytesPerSecIndex++); |
||
| 412 | |||
| 413 | if (dwBytesPerSecIndex < MAX_WMA_AVG_BYTES_PER_SEC_ENTRIES) |
||
| 414 | { |
||
| 415 | dwReturn = dwBlockAlignIndex | (dwBytesPerSecIndex << 5); |
||
| 416 | } |
||
| 417 | } |
||
| 418 | |||
| 419 | return dwReturn; |
||
| 420 | } |
||
| 421 | |||
| 422 | |||
| 423 | void XMA2FillFormatEx(XMA2WAVEFORMATEX *fmt, WORD blockCount, const struct WAVEBANKENTRY* entry) const; |
||
| 424 | |||
| 425 | DWORD AdpcmSamplesPerBlock() const |
||
| 426 | { |
||
| 427 | DWORD nBlockAlign = (wBlockAlign + ADPCM_MINIWAVEFORMAT_BLOCKALIGN_CONVERSION_OFFSET) * nChannels; |
||
| 428 | return nBlockAlign * 2 / (DWORD)nChannels - 12; |
||
| 429 | } |
||
| 430 | |||
| 431 | void AdpcmFillCoefficientTable(ADPCMWAVEFORMAT *fmt) const |
||
| 432 | { |
||
| 433 | // These are fixed since we are always using MS ADPCM |
||
| 434 | fmt->wNumCoef = 7; /* MSADPCM_NUM_COEFFICIENTS */ |
||
| 435 | |||
| 436 | static ADPCMCOEFSET aCoef[7] = { { 256, 0}, {512, -256}, {0,0}, {192,64}, {240,0}, {460, -208}, {392,-232} }; |
||
| 437 | memcpy( &fmt->aCoef, aCoef, sizeof(aCoef) ); |
||
| 438 | } |
||
| 439 | |||
| 440 | #endif // __cplusplus |
||
| 441 | |||
| 442 | } WAVEBANKMINIWAVEFORMAT, *LPWAVEBANKMINIWAVEFORMAT; |
||
| 443 | |||
| 444 | typedef const WAVEBANKMINIWAVEFORMAT *LPCWAVEBANKMINIWAVEFORMAT; |
||
| 445 | |||
| 446 | // |
||
| 447 | // Entry meta-data |
||
| 448 | // |
||
| 449 | |||
| 450 | typedef struct WAVEBANKENTRY |
||
| 451 | { |
||
| 452 | union |
||
| 453 | { |
||
| 454 | struct |
||
| 455 | { |
||
| 456 | // Entry flags |
||
| 457 | DWORD dwFlags : 4; |
||
| 458 | |||
| 459 | // Duration of the wave, in units of one sample. |
||
| 460 | // For instance, a ten second long wave sampled |
||
| 461 | // at 48KHz would have a duration of 480,000. |
||
| 462 | // This value is not affected by the number of |
||
| 463 | // channels, the number of bits per sample, or the |
||
| 464 | // compression format of the wave. |
||
| 465 | DWORD Duration : 28; |
||
| 466 | }; |
||
| 467 | DWORD dwFlagsAndDuration; |
||
| 468 | }; |
||
| 469 | |||
| 470 | WAVEBANKMINIWAVEFORMAT Format; // Entry format. |
||
| 471 | WAVEBANKREGION PlayRegion; // Region within the wave data segment that contains this entry. |
||
| 472 | WAVEBANKSAMPLEREGION LoopRegion; // Region within the wave data (in samples) that should loop. |
||
| 473 | |||
| 474 | #ifdef __cplusplus |
||
| 475 | |||
| 476 | void SwapBytes(void) |
||
| 477 | { |
||
| 478 | XACTWaveBank::SwapBytes(dwFlagsAndDuration); |
||
| 479 | Format.SwapBytes(); |
||
| 480 | PlayRegion.SwapBytes(); |
||
| 481 | LoopRegion.SwapBytes(); |
||
| 482 | } |
||
| 483 | |||
| 484 | #endif // __cplusplus |
||
| 485 | |||
| 486 | } WAVEBANKENTRY, *LPWAVEBANKENTRY; |
||
| 487 | |||
| 488 | typedef const WAVEBANKENTRY *LPCWAVEBANKENTRY; |
||
| 489 | |||
| 490 | // |
||
| 491 | // Compact entry meta-data |
||
| 492 | // |
||
| 493 | |||
| 494 | typedef struct WAVEBANKENTRYCOMPACT |
||
| 495 | { |
||
| 496 | DWORD dwOffset : 21; // Data offset, in sectors |
||
| 497 | DWORD dwLengthDeviation : 11; // Data length deviation, in bytes |
||
| 498 | |||
| 499 | #ifdef __cplusplus |
||
| 500 | |||
| 501 | void SwapBytes(void) |
||
| 502 | { |
||
| 503 | XACTWaveBank::SwapBytes(*(LPDWORD)this); |
||
| 504 | } |
||
| 505 | |||
| 506 | #endif // __cplusplus |
||
| 507 | |||
| 508 | } WAVEBANKENTRYCOMPACT, *LPWAVEBANKENTRYCOMPACT; |
||
| 509 | |||
| 510 | typedef const WAVEBANKENTRYCOMPACT *LPCWAVEBANKENTRYCOMPACT; |
||
| 511 | |||
| 512 | // |
||
| 513 | // Bank data segment |
||
| 514 | // |
||
| 515 | |||
| 516 | typedef struct WAVEBANKDATA |
||
| 517 | { |
||
| 518 | DWORD dwFlags; // Bank flags |
||
| 519 | DWORD dwEntryCount; // Number of entries in the bank |
||
| 520 | CHAR szBankName[WAVEBANK_BANKNAME_LENGTH]; // Bank friendly name |
||
| 521 | DWORD dwEntryMetaDataElementSize; // Size of each entry meta-data element, in bytes |
||
| 522 | DWORD dwEntryNameElementSize; // Size of each entry name element, in bytes |
||
| 523 | DWORD dwAlignment; // Entry alignment, in bytes |
||
| 524 | WAVEBANKMINIWAVEFORMAT CompactFormat; // Format data for compact bank |
||
| 525 | FILETIME BuildTime; // Build timestamp |
||
| 526 | |||
| 527 | #ifdef __cplusplus |
||
| 528 | |||
| 529 | void SwapBytes(void) |
||
| 530 | { |
||
| 531 | XACTWaveBank::SwapBytes(dwFlags); |
||
| 532 | XACTWaveBank::SwapBytes(dwEntryCount); |
||
| 533 | XACTWaveBank::SwapBytes(dwEntryMetaDataElementSize); |
||
| 534 | XACTWaveBank::SwapBytes(dwEntryNameElementSize); |
||
| 535 | XACTWaveBank::SwapBytes(dwAlignment); |
||
| 536 | CompactFormat.SwapBytes(); |
||
| 537 | XACTWaveBank::SwapBytes(BuildTime.dwLowDateTime); |
||
| 538 | XACTWaveBank::SwapBytes(BuildTime.dwHighDateTime); |
||
| 539 | } |
||
| 540 | |||
| 541 | #endif // __cplusplus |
||
| 542 | |||
| 543 | } WAVEBANKDATA, *LPWAVEBANKDATA; |
||
| 544 | |||
| 545 | typedef const WAVEBANKDATA *LPCWAVEBANKDATA; |
||
| 546 | |||
| 547 | inline void WAVEBANKMINIWAVEFORMAT::XMA2FillFormatEx(XMA2WAVEFORMATEX *fmt, WORD blockCount, const WAVEBANKENTRY* entry) const |
||
| 548 | { |
||
| 549 | // Note caller is responsbile for filling out fmt->wfx with other helper functions. |
||
| 550 | |||
| 551 | fmt->NumStreams = (WORD)( (nChannels + 1) / 2 ); |
||
| 552 | |||
| 553 | switch (nChannels) |
||
| 554 | { |
||
| 555 | case 1: fmt->ChannelMask = SPEAKER_MONO; break; |
||
| 556 | case 2: fmt->ChannelMask = SPEAKER_STEREO; break; |
||
| 557 | case 3: fmt->ChannelMask = SPEAKER_2POINT1; break; |
||
| 558 | case 4: fmt->ChannelMask = SPEAKER_QUAD; break; |
||
| 559 | case 5: fmt->ChannelMask = SPEAKER_4POINT1; break; |
||
| 560 | case 6: fmt->ChannelMask = SPEAKER_5POINT1; break; |
||
| 561 | case 7: fmt->ChannelMask = SPEAKER_5POINT1 | SPEAKER_BACK_CENTER; break; |
||
| 562 | case 8: fmt->ChannelMask = SPEAKER_7POINT1; break; |
||
| 563 | default: fmt->ChannelMask = 0; break; |
||
| 564 | } |
||
| 565 | |||
| 566 | fmt->SamplesEncoded = entry->Duration; |
||
| 567 | fmt->BytesPerBlock = 65536; /* XACT_FIXED_XMA_BLOCK_SIZE */ |
||
| 568 | |||
| 569 | fmt->PlayBegin = entry->PlayRegion.dwOffset; |
||
| 570 | fmt->PlayLength = entry->PlayRegion.dwLength; |
||
| 571 | |||
| 572 | if (entry->LoopRegion.dwTotalSamples > 0) |
||
| 573 | { |
||
| 574 | fmt->LoopBegin = entry->LoopRegion.dwStartSample; |
||
| 575 | fmt->LoopLength = entry->LoopRegion.dwTotalSamples; |
||
| 576 | fmt->LoopCount = 0xff; /* XACTLOOPCOUNT_INFINITE */ |
||
| 577 | } |
||
| 578 | else |
||
| 579 | { |
||
| 580 | fmt->LoopBegin = 0; |
||
| 581 | fmt->LoopLength = 0; |
||
| 582 | fmt->LoopCount = 0; |
||
| 583 | } |
||
| 584 | |||
| 585 | fmt->EncoderVersion = 4; // XMAENCODER_VERSION_XMA2 |
||
| 586 | |||
| 587 | fmt->BlockCount = blockCount; |
||
| 588 | } |
||
| 589 | |||
| 590 | #ifdef _M_PPCBE |
||
| 591 | #pragma bitfield_order(pop) |
||
| 592 | #endif |
||
| 593 | |||
| 594 | #pragma warning(pop) |
||
| 595 | #pragma pack(pop) |
||
| 596 | |||
| 597 | #endif // __XACTWB_H__ |
||
| 598 |